protractor#Key TypeScript Examples

The following examples show how to use protractor#Key. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: keyboard-event.e2e-spec.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Does the following steps:
 *
 * 1. Starts the testing app
 * 2. Embeds a microfrontend
 * 3. Registers the passed keystroke for propagation on the outlet
 * 4. Presses passed keys in the embedded microfrontend
 */
async function setupAndPressKeystroke(instructions: {keystrokeToRegister: string; keysToPress: string[]}): Promise<void> {
  const testingAppPO = new TestingAppPO();
  const pagePOs = await testingAppPO.navigateTo({
    microfrontend: Microfrontend1PagePO,
  });

  const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
  await outletPO.setKeystrokesViaAttr(instructions.keystrokeToRegister);

  const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
  await microfrontendPagePO.clickInputField();
  await sendKeys(Key.chord(...instructions.keysToPress));
}
Example #2
Source File: spec.util.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Enters the given text into the given input field.
 *
 * By default, the text is set directly as input to the field, because 'sendKeys' is very slow.
 */
export async function enterText(text: string, elementFinder: ElementFinder, inputStrategy: 'sendKeys' | 'setValue' = 'setValue'): Promise<void> {
  const enterTextFn = async (): Promise<void> => {
    switch (inputStrategy) {
      case 'sendKeys': { // send keys is slow for long texts
        await elementFinder.clear();
        await elementFinder.click();
        await sendKeys(text);
        break;
      }
      case 'setValue': {
        // fire the 'input' event manually because not fired when setting the value with javascript
        await elementFinder.click();
        await browser.executeScript('arguments[0].value=arguments[1]; arguments[0].dispatchEvent(new Event(\'input\'));', elementFinder.getWebElement(), text);
        await sendKeys(Key.TAB);
        break;
      }
      default: {
        throw Error('[UnsupportedStrategyError] Input strategy not supported.');
      }
    }
  };

  try {
    await enterTextFn();
  }
  catch (error) {
    // Maybe, the element is not interactable because not scrolled into view. Try again, but scroll it into view first.
    // This error often occurs on GitHub CI, but not when running tests locally.
    if (error instanceof Error && error.name === 'ElementNotVisibleError') {
      console.log(`[ElementNotVisibleError] Element not interactable: ${elementFinder.locator().toString()}. Scrolling it into view and trying to enter text again.`, error);
      await browser.executeScript('arguments[0].scrollIntoView()', elementFinder.getWebElement());
      await enterTextFn();
      console.log(`Text successfully entered into input field: ${elementFinder.locator().toString()}`);
    }
    else {
      throw error;
    }
  }
}
Example #3
Source File: router-outlet-settings.po.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 5 votes vote down vote up
public async close(): Promise<void> {
    await this._switchToIframeFn();
    await sendKeys(Key.ESCAPE);
  }
Example #4
Source File: keyboard-event.e2e-spec.ts    From scion-microfrontend-platform with Eclipse Public License 2.0 4 votes vote down vote up
describe('KeyboardEvent', () => {

  installSeleniumWebDriverClickFix();

  it('should receive keyboard events for the \'m\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.m',
      keysToPress: ['m'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='m', control=false, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.m',
      keysToPress: ['m'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='m', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'control.m\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.control.m',
      keysToPress: [Key.CONTROL, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='m', control=true, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.control.m',
      keysToPress: [Key.CONTROL, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='m', control=true, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'control.shift.m\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.control.shift.m',
      keysToPress: [Key.CONTROL, Key.SHIFT, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='M', control=true, shift=true, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.control.shift.m',
      keysToPress: [Key.CONTROL, Key.SHIFT, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='M', control=true, shift=true, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'control.shift.alt.m\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.control.shift.alt.m',
      keysToPress: [Key.CONTROL, Key.SHIFT, Key.ALT, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='M', control=true, shift=true, alt=true, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.control.shift.alt.m',
      keysToPress: [Key.CONTROL, Key.SHIFT, Key.ALT, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='M', control=true, shift=true, alt=true, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'control.shift.alt.meta.m\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.control.shift.alt.meta.m',
      keysToPress: [Key.CONTROL, Key.SHIFT, Key.ALT, Key.META, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='M', control=true, shift=true, alt=true, meta=true]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.control.shift.alt.meta.m',
      keysToPress: [Key.CONTROL, Key.SHIFT, Key.ALT, Key.META, 'm'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='M', control=true, shift=true, alt=true, meta=true]`,
    ]));
  });

  it('should receive keyboard events for the \'dot\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.dot',
      keysToPress: ['.'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='.', control=false, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.dot',
      keysToPress: ['.'],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='.', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'space\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.space',
      keysToPress: [' '],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key=' ', control=false, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.space',
      keysToPress: [' '],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key=' ', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'escape\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.escape',
      keysToPress: [Key.ESCAPE],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='Escape', control=false, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.escape',
      keysToPress: [Key.ESCAPE],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='Escape', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'enter\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.enter',
      keysToPress: [Key.ENTER],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='Enter', control=false, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.enter',
      keysToPress: [Key.ENTER],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='Enter', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'f7\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.f7',
      keysToPress: [Key.F7],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='F7', control=false, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.f7',
      keysToPress: [Key.F7],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='F7', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events for the \'backspace\' keystroke', async () => {
    await setupAndPressKeystroke({
      keystrokeToRegister: 'keydown.backspace',
      keysToPress: [Key.BACK_SPACE],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='Backspace', control=false, shift=false, alt=false, meta=false]`,
    ]));

    await setupAndPressKeystroke({
      keystrokeToRegister: 'keyup.backspace',
      keysToPress: [Key.BACK_SPACE],
    });
    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeyup] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeyup] [SYNTHETIC] [outletContext=n/a, key='Backspace', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should receive keyboard events from nested microfrontends', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });
    // Register the keystroke in the top-level outlet
    await pagePOs.get<BrowserOutletPO>('outlet1').setKeystrokesViaAttr('keydown.control.m');

    // Enter the keystroke in the lowermost microfrontend
    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, 'm'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=outlet3, key='m', control=true, shift=false, alt=false, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=outlet2, key='m', control=true, shift=false, alt=false, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=outlet1, key='m', control=true, shift=false, alt=false, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='m', control=true, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should not receive the keyboard events for a keystroke registered in a nested microfrontend', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });
    // Register the keystroke in the middle outlet, but not in the parent
    await pagePOs.get<BrowserOutletPO>('outlet2').setKeystrokesViaAttr('keydown.control.m');

    // Enter the keystroke in the lowermost microfrontend
    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, 'm'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=outlet3, key='m', control=true, shift=false, alt=false, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=outlet2, key='m', control=true, shift=false, alt=false, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=outlet1, key='m', control=true, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should not receive keyboard events for not registered keystrokes', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      microfrontend: Microfrontend1PagePO,
    });

    const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
    await outletPO.setKeystrokesViaAttr('keydown.alt.x');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.ALT, 'x'));
    await sendKeys(Key.chord(Key.ALT, 'v'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='x', control=false, shift=false, alt=true, meta=false]`,
    ]));
  });

  it('should not prevent default action if keyboard flags not set', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
    await outletPO.setKeystrokesViaAttr('keydown.control.alt.shift.s');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=false]`,
    ]));
  });

  it('should not prevent default action if `preventDefault` is set to `false`', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
    await outletPO.setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=false}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=false]`,
    ]));
  });

  it('should prevent default action if `preventDefault` is set to `true`', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
    await outletPO.setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=true}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=true]`,
    ]));
  });

  it('should prevent default action if `preventDefault` is set to `true` in outlet3', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    await pagePOs.get<BrowserOutletPO>('microfrontend:outlet').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet3').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=true}');
    await pagePOs.get<BrowserOutletPO>('outlet2').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=false}');
    await pagePOs.get<BrowserOutletPO>('outlet1').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=false}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=true]`,
    ]));
  });

  it('should prevent default action if `preventDefault` is set to `true` in outlet2', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    await pagePOs.get<BrowserOutletPO>('microfrontend:outlet').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet3').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet2').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=true}');
    await pagePOs.get<BrowserOutletPO>('outlet1').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=false}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=true]`,
    ]));
  });

  it('should prevent default action if `preventDefault` is set to `true` in outlet1', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    await pagePOs.get<BrowserOutletPO>('microfrontend:outlet').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet3').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet2').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet1').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=true}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=true]`,
    ]));
  });

  it('should not prevent default action if `preventDefault` is set to `false` in outlet3', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    await pagePOs.get<BrowserOutletPO>('microfrontend:outlet').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet3').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=false}');
    await pagePOs.get<BrowserOutletPO>('outlet2').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=true}');
    await pagePOs.get<BrowserOutletPO>('outlet1').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=true}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=false]`,
    ]));
  });

  it('should not prevent default action if `preventDefault` is set to `false` in outlet2', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    await pagePOs.get<BrowserOutletPO>('microfrontend:outlet').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet3').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet2').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=false}');
    await pagePOs.get<BrowserOutletPO>('outlet1').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=true}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=false]`,
    ]));
  });

  it('should not prevent default action if `preventDefault` is set to `false` in outlet1', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      outlet1: {
        outlet2: {
          outlet3: {
            microfrontend: Microfrontend1PagePO,
          },
        },
      },
    });

    await pagePOs.get<BrowserOutletPO>('microfrontend:outlet').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet3').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet2').setKeystrokesViaAttr('keydown.control.alt.shift.s');
    await pagePOs.get<BrowserOutletPO>('outlet1').setKeystrokesViaAttr('keydown.control.alt.shift.s{preventDefault=false}');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.CONTROL, Key.ALT, Key.SHIFT, 's'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[TRUSTED]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [TRUSTED] [outletContext=microfrontend, key='S', control=true, shift=true, alt=true, meta=false, defaultPrevented=false]`,
    ]));
  });

  it('should unsubscribe keyboard event handlers when keystrokes change, thus avoiding subscription leaks', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      microfrontend: Microfrontend1PagePO,
    });

    const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
    await outletPO.setKeystrokesViaAttr('keydown.alt.x');
    await outletPO.setKeystrokesViaAttr('keydown.alt.y'); // override the keystroke above by this one

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.ALT, 'x'));
    await sendKeys(Key.chord(Key.ALT, 'y'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='y', control=false, shift=false, alt=true, meta=false]`,
    ]));
  });

  it('should allow registering multiple keystrokes via <sci-router-outlet> attribute', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      microfrontend: Microfrontend1PagePO,
    });

    const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
    await outletPO.setKeystrokesViaAttr('keydown.alt.x,keydown.alt.y,keydown.m');

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.ALT, 'x'));
    await sendKeys(Key.chord(Key.ALT, 'y'));
    await sendKeys(Key.chord('m'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='x', control=false, shift=false, alt=true, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='y', control=false, shift=false, alt=true, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='m', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });

  it('should allow registering multiple keystrokes via <sci-router-outlet> DOM element', async () => {
    const testingAppPO = new TestingAppPO();
    const pagePOs = await testingAppPO.navigateTo({
      microfrontend: Microfrontend1PagePO,
    });

    const outletPO = pagePOs.get<BrowserOutletPO>('microfrontend:outlet');
    await outletPO.setKeystrokesViaDom(['keydown.alt.x', 'keydown.alt.y', 'keydown.m']);

    const microfrontendPagePO = pagePOs.get<Microfrontend1PagePO>('microfrontend');
    await microfrontendPagePO.clickInputField();
    await sendKeys(Key.chord(Key.ALT, 'x'));
    await sendKeys(Key.chord(Key.ALT, 'y'));
    await sendKeys(Key.chord('m'));

    await expect(await consumeBrowserLog(Level.DEBUG, /AppComponent::document:onkeydown] \[SYNTHETIC]/)).toEqual(jasmine.arrayWithExactContents([
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='x', control=false, shift=false, alt=true, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='y', control=false, shift=false, alt=true, meta=false]`,
      `[AppComponent::document:onkeydown] [SYNTHETIC] [outletContext=n/a, key='m', control=false, shift=false, alt=false, meta=false]`,
    ]));
  });
});
Example #5
Source File: app.e2e-spec.ts    From s-libs with MIT License 4 votes vote down vote up
describe('integration App', () => {
  let page: AppPage;

  beforeEach(async () => {
    page = new AppPage();
    await page.navigateTo();
  });

  afterEach(async () => {
    // Assert that there are no errors emitted from the browser
    const logs = await browser.manage().logs().get(logging.Type.BROWSER);
    expect(logs).not.toContain(
      jasmine.objectContaining({
        level: logging.Level.SEVERE,
      } as logging.Entry),
    );
  });

  async function clearValue(control: string | ElementFinder): Promise<void> {
    control = getControl(control);

    // https://github.com/angular/protractor/issues/4343#issuecomment-350106755
    await control.sendKeys(Key.chord(Key.CONTROL, 'a'));
    await control.sendKeys(Key.BACK_SPACE);
    await control.clear();
  }

  function getControl(control: string | ElementFinder): ElementFinder {
    if (typeof control === 'string') {
      return getInput(control);
    } else {
      return control;
    }
  }

  function getInput(type: string): ElementFinder {
    let css = 'input';
    if (type) {
      css += `[type="${type}"]`;
    } else {
      css += ':not([type])';
    }
    return element(by.css(css));
  }

  describe('free text controls (and color)', () => {
    function textarea(): ElementFinder {
      return element(by.css('textarea'));
    }

    interface ExpectFreeTextOptions {
      isColor?: boolean;
    }

    async function testControl(
      control: string | ElementFinder,
      value: string,
      options?: ExpectFreeTextOptions,
    ): Promise<void> {
      await clearValue(control);
      await expectValue('');
      await getControl(control).sendKeys(value);
      await expectValue(value, options);
    }

    async function expectValue(
      value: string,
      { isColor = false }: ExpectFreeTextOptions = {},
    ): Promise<void> {
      const stripped = value.replace(/[\r\n]/g, '');
      expect(await getInput('').getAttribute('value')).toEqual(stripped);
      expect(await getInput('text').getAttribute('value')).toEqual(stripped);
      expect(await getInput('search').getAttribute('value')).toEqual(stripped);
      expect(await getInput('tel').getAttribute('value')).toEqual(stripped);
      expect(await getInput('password').getAttribute('value')).toEqual(
        stripped,
      );
      expect(await getInput('email').getAttribute('value')).toEqual(stripped);
      expect(await getInput('url').getAttribute('value')).toEqual(stripped);
      expect(await textarea().getAttribute('value')).toEqual(value);

      expect(await getInput('color').getAttribute('value')).toEqual(
        isColor ? value : '#000000',
      );
    }

    it('work', async () => {
      await expectValue('initial text');

      await testControl('', 'default input');
      await testControl('text', 'text input');
      await testControl('search', 'search input');
      await testControl('tel', 'tel input');
      await testControl('password', 'password input');
      await testControl('email', '[email protected]');
      await testControl('url', 'http://www.input.com/url');
      await testControl('', '#123456', { isColor: true });
      await testControl(textarea(), 'textarea\nvalue');

      // https://stackoverflow.com/q/36402624/1836506
      browser.executeScript(`
        input = document.querySelector('input[type="color"]');
        input.value = '#654321';
        input.dispatchEvent(new Event('input'));
      `);
      await expectValue('#654321', { isColor: true });
    });
  });

  describe('number controls', () => {
    async function expectValue(value: string): Promise<void> {
      expect(await getInput('number').getAttribute('value')).toEqual(value);
      expect(await getInput('range').getAttribute('value')).toEqual(
        value || '50',
      );
    }

    it('work', async () => {
      await expectValue('42');

      await clearValue('number');
      await expectValue('');
      await getInput('number').sendKeys('75');
      await expectValue('75');

      await browser
        .actions()
        .dragAndDrop(await getInput('range').getWebElement(), { x: -99, y: 0 })
        .perform();
      await expectValue('0');
    });
  });

  describe('choose one controls', () => {
    function getDropdown(): ElementFinder {
      return element(by.css('select:not([multiple])'));
    }

    function getRadio(value: string): ElementFinder {
      return element(by.css(`input[type="radio"][value="${value}"]`));
    }

    async function expectValue(value: string): Promise<void> {
      expect(await getDropdown().getAttribute('value')).toEqual(value);
      for (const city of cities) {
        expect(await getRadio(city).getAttribute('checked')).toEqual(
          city === value ? 'true' : null!,
        );
      }
    }

    it('work', async () => {
      await expectValue('Nairobi');

      await element(by.cssContainingText('option', 'San Francisco')).click();
      await expectValue('San Francisco');

      await getRadio('Gulu').click();
      await expectValue('Gulu');
    });
  });

  describe('choose many controls', () => {
    function getOption(value: string): ElementFinder {
      return element(by.cssContainingText('select[multiple] option', value));
    }

    function getCheck(value: string): ElementFinder {
      return element(by.css(`input[type="checkbox"][value="${value}"]`));
    }

    async function expectValues(values: string[]): Promise<void> {
      for (const city of cities) {
        const expected = values.includes(city) ? 'true' : null!;
        expect(await getOption(city).getAttribute('checked')).toEqual(expected);
        expect(await getCheck(city).getAttribute('checked')).toEqual(expected);
      }
    }

    it('work', async () => {
      await expectValues(['Nairobi', 'Gulu']);

      await getOption('Gulu').click();
      await element(by.cssContainingText('button', 'v')).click();
      await expectValues(['Nairobi']);

      await getCheck('Nairobi').click();
      await element(by.cssContainingText('button', '^')).click();
      await expectValues([]);
    });
  });

  describe('date and time controls', () => {
    async function testControl(
      type: string,
      keys: string,
      value: string,
      week: string,
    ): Promise<void> {
      await clearDate(type);
      await expectValue('', '');
      await getInput(type).sendKeys(keys);
      await propagate(type);
      await expectValue(value, week);
    }

    async function clearDate(type: string): Promise<void> {
      const control = getInput(type);
      await control.sendKeys(Key.BACK_SPACE);
      await propagate(type);
    }

    async function propagate(type: string): Promise<void> {
      await element(by.cssContainingText('button', type + ' flush')).click();
    }

    async function expectValue(datetime: string, week: string): Promise<void> {
      expect(await getInput('datetime-local').getAttribute('value')).toEqual(
        datetime,
      );
      expect(await getInput('date').getAttribute('value')).toEqual(
        datetime.substr(0, 10),
      );
      expect(await getInput('month').getAttribute('value')).toEqual(
        datetime.substr(0, 7),
      );
      expect(await getInput('week').getAttribute('value')).toEqual(week);
      expect(await getInput('time').getAttribute('value')).toEqual(
        datetime.substr(11),
      );
    }

    it('work', async () => {
      await expectValue('1980-11-04T10:30', '1980-W45');
      await testControl(
        'datetime-local',
        `06211975${Key.TAB}0426p`,
        '1975-06-21T16:26',
        '1975-W25',
      );
      await testControl('date', `07041776`, '1776-07-04T00:00', '1776-W27');
      await testControl(
        'month',
        `d${Key.TAB}1999`,
        '1999-12-01T00:00',
        '1999-W48',
      );
      await testControl('week', `412032`, '2032-10-09T00:00', '2032-W41');
      await testControl('time', `0844p`, '2000-01-01T20:44', '2000-W01');
    });
  });
});