mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
326f8bb32f
* Builds the e2e app with Bazel * Serves the e2e app with Bazel * Runs the e2e tests with Bazel protractor rules
210 lines
7.5 KiB
TypeScript
210 lines
7.5 KiB
TypeScript
import {browser, by, element, ExpectedConditions, Key, protractor} from 'protractor';
|
|
import {
|
|
expectAlignedWith,
|
|
expectFocusOn,
|
|
expectLocation,
|
|
expectToExist,
|
|
pressKeys,
|
|
} from '../util/index';
|
|
|
|
const presenceOf = ExpectedConditions.presenceOf;
|
|
const not = ExpectedConditions.not;
|
|
|
|
|
|
describe('menu', () => {
|
|
const menuSelector = '.mat-menu-panel';
|
|
const page = {
|
|
menu: () => element(by.css('.mat-menu-panel')),
|
|
start: () => element(by.id('start')),
|
|
trigger: () => element(by.id('trigger')),
|
|
triggerTwo: () => element(by.id('trigger-two')),
|
|
backdrop: () => element(by.css('.cdk-overlay-backdrop')),
|
|
items: (index: number) => element.all(by.css('[mat-menu-item]')).get(index),
|
|
textArea: () => element(by.id('text')),
|
|
beforeTrigger: () => element(by.id('before-t')),
|
|
aboveTrigger: () => element(by.id('above-t')),
|
|
combinedTrigger: () => element(by.id('combined-t')),
|
|
beforeMenu: () => element(by.css('.mat-menu-panel.before')),
|
|
aboveMenu: () => element(by.css('.mat-menu-panel.above')),
|
|
combinedMenu: () => element(by.css('.mat-menu-panel.combined')),
|
|
getResultText: () => page.textArea().getText(),
|
|
};
|
|
|
|
beforeEach(async () => await browser.get('/menu'));
|
|
|
|
it('should open menu when the trigger is clicked', async () => {
|
|
await expectToExist(menuSelector, false);
|
|
await page.trigger().click();
|
|
|
|
await expectToExist(menuSelector);
|
|
expect(await page.menu().getText()).toEqual('One\nTwo\nThree\nFour');
|
|
});
|
|
|
|
it('should close menu when menu item is clicked', async () => {
|
|
await page.trigger().click();
|
|
await page.items(0).click();
|
|
await expectToExist(menuSelector, false);
|
|
});
|
|
|
|
it('should run click handlers on regular menu items', async () => {
|
|
await page.trigger().click();
|
|
await page.items(0).click();
|
|
expect(await page.getResultText()).toEqual('one');
|
|
|
|
await page.trigger().click();
|
|
await page.items(1).click();
|
|
expect(await page.getResultText()).toEqual('two');
|
|
});
|
|
|
|
it('should run not run click handlers on disabled menu items', async () => {
|
|
await page.trigger().click();
|
|
await page.items(2).click();
|
|
expect(await page.getResultText()).toEqual('');
|
|
});
|
|
|
|
it('should support multiple triggers opening the same menu', async () => {
|
|
await page.triggerTwo().click();
|
|
|
|
expect(await page.menu().getText()).toEqual('One\nTwo\nThree\nFour');
|
|
await expectAlignedWith(page.menu(), '#trigger-two');
|
|
|
|
await page.backdrop().click();
|
|
await browser.wait(not(presenceOf(element(by.css(menuSelector)))));
|
|
await browser.wait(not(presenceOf(element(by.css('.cdk-overlay-backdrop')))));
|
|
|
|
await page.trigger().click();
|
|
|
|
expect(await page.menu().getText()).toEqual('One\nTwo\nThree\nFour');
|
|
await expectAlignedWith(page.menu(), '#trigger');
|
|
|
|
await page.backdrop().click();
|
|
|
|
await browser.wait(not(presenceOf(element(by.css(menuSelector)))));
|
|
await browser.wait(not(presenceOf(element(by.css('.cdk-overlay-backdrop')))));
|
|
});
|
|
|
|
it('should mirror classes on host to menu template in overlay', async () => {
|
|
await page.trigger().click();
|
|
expect(await page.menu().getAttribute('class')).toContain('mat-menu-panel');
|
|
expect(await page.menu().getAttribute('class')).toContain('custom');
|
|
});
|
|
|
|
describe('keyboard events', () => {
|
|
beforeEach(async () => {
|
|
// click start button to avoid tabbing past navigation
|
|
await page.start().click();
|
|
await pressKeys(Key.TAB);
|
|
});
|
|
|
|
it('should auto-focus the first item when opened with ENTER', async () => {
|
|
await pressKeys(Key.ENTER);
|
|
await expectFocusOn(page.items(0));
|
|
});
|
|
|
|
it('should auto-focus the first item when opened with SPACE', async () => {
|
|
await pressKeys(Key.SPACE);
|
|
await expectFocusOn(page.items(0));
|
|
});
|
|
|
|
it('should focus the first item when opened by mouse', async () => {
|
|
await page.trigger().click();
|
|
await expectFocusOn(page.items(0));
|
|
});
|
|
|
|
it('should focus subsequent items when down arrow is pressed', async () => {
|
|
await pressKeys(Key.ENTER, Key.DOWN);
|
|
await expectFocusOn(page.items(1));
|
|
});
|
|
|
|
it('should focus previous items when up arrow is pressed', async () => {
|
|
await pressKeys(Key.ENTER, Key.DOWN, Key.UP);
|
|
await expectFocusOn(page.items(0));
|
|
});
|
|
|
|
it('should skip disabled items using arrow keys', async () => {
|
|
await pressKeys(Key.ENTER, Key.DOWN, Key.DOWN);
|
|
await expectFocusOn(page.items(3));
|
|
|
|
await pressKeys(Key.UP);
|
|
await expectFocusOn(page.items(1));
|
|
});
|
|
|
|
it('should close the menu when tabbing past items', async () => {
|
|
await pressKeys(Key.ENTER, Key.TAB);
|
|
await expectToExist(menuSelector, false);
|
|
|
|
await pressKeys(Key.TAB, Key.ENTER);
|
|
await expectToExist(menuSelector);
|
|
|
|
await pressKeys(protractor.Key.chord(Key.SHIFT, Key.TAB));
|
|
await expectToExist(menuSelector, false);
|
|
});
|
|
|
|
it('should wrap back to menu when arrow keying past items', async () => {
|
|
let down = Key.DOWN;
|
|
await pressKeys(Key.ENTER, down, down, down);
|
|
await expectFocusOn(page.items(0));
|
|
|
|
await pressKeys(Key.UP);
|
|
await expectFocusOn(page.items(3));
|
|
});
|
|
|
|
it('should focus before and after trigger when tabbing past items', async () => {
|
|
let shiftTab = protractor.Key.chord(Key.SHIFT, Key.TAB);
|
|
|
|
await pressKeys(Key.ENTER, Key.TAB);
|
|
await expectFocusOn(page.triggerTwo());
|
|
|
|
// navigate back to trigger
|
|
await pressKeys(shiftTab, Key.ENTER, shiftTab);
|
|
await expectFocusOn(page.start());
|
|
});
|
|
|
|
});
|
|
|
|
describe('position - ', () => {
|
|
|
|
it('should default menu alignment to "after below" when not set', async () => {
|
|
await page.trigger().click();
|
|
|
|
// menu.x should equal trigger.x, menu.y should equal trigger.y
|
|
await expectAlignedWith(page.menu(), '#trigger');
|
|
});
|
|
|
|
it('should align overlay end to origin end when x-position is "before"', async () => {
|
|
await page.beforeTrigger().click();
|
|
|
|
const trigger = await page.beforeTrigger().getLocation();
|
|
|
|
// the menu's right corner must be attached to the trigger's right corner.
|
|
// menu = 112px wide. trigger = 60px wide. 112 - 60 = 52px of menu to the left of trigger.
|
|
// trigger.x (left corner) - 52px (menu left of trigger) = expected menu.x (left corner)
|
|
// menu.y should equal trigger.y because only x position has changed.
|
|
await expectLocation(page.beforeMenu(), {x: trigger.x - 52, y: trigger.y});
|
|
});
|
|
|
|
it('should align overlay bottom to origin bottom when y-position is "above"', async () => {
|
|
await page.aboveTrigger().click();
|
|
|
|
const trigger = await page.aboveTrigger().getLocation();
|
|
|
|
// the menu's bottom corner must be attached to the trigger's bottom corner.
|
|
// menu.x should equal trigger.x because only y position has changed.
|
|
// menu = 64px high. trigger = 20px high. 64 - 20 = 44px of menu extending up past trigger.
|
|
// trigger.y (top corner) - 44px (menu above trigger) = expected menu.y (top corner)
|
|
await expectLocation(page.aboveMenu(), {x: trigger.x, y: trigger.y - 44});
|
|
});
|
|
|
|
it('should align menu to top left of trigger when "below" and "above"', async () => {
|
|
await page.combinedTrigger().click();
|
|
|
|
const trigger = await page.combinedTrigger().getLocation();
|
|
|
|
// trigger.x (left corner) - 52px (menu left of trigger) = expected menu.x
|
|
// trigger.y (top corner) - 44px (menu above trigger) = expected menu.y
|
|
await expectLocation(page.combinedMenu(), {x: trigger.x - 52, y: trigger.y - 44});
|
|
});
|
|
|
|
});
|
|
});
|