From c1907809a8ea294e7d6d27856364a499a5b7e725 Mon Sep 17 00:00:00 2001 From: George Kalpakas Date: Wed, 4 Nov 2020 20:45:33 +0200 Subject: [PATCH] test(elements): add integration tests for Angular Elements using `ShadowDom` (#39452) Previously, the project used for running integration tests for Angular Elements declared a component that used `ShadowDom` for view encopsulation, but it did not include any tests to verify that the view was updated correctly. This commit adds the missing tests. PR Close #39452 --- integration/ng_elements/e2e/app.e2e-spec.ts | 40 +++++++++++++++----- integration/ng_elements/src/app.ts | 2 +- integration/ng_elements/src/elements.ts | 8 ++-- integration/ng_elements/src/hello-world.html | 2 +- integration/ng_elements/src/main.ts | 13 ++++--- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/integration/ng_elements/e2e/app.e2e-spec.ts b/integration/ng_elements/e2e/app.e2e-spec.ts index 84acb3505b..8da6d63c43 100644 --- a/integration/ng_elements/e2e/app.e2e-spec.ts +++ b/integration/ng_elements/e2e/app.e2e-spec.ts @@ -1,22 +1,42 @@ -import { browser, element, ExpectedConditions as EC, by } from 'protractor'; +import {browser, by, element, ElementFinder, ExpectedConditions as EC} from 'protractor'; browser.waitForAngularEnabled(false); describe('Element E2E Tests', function () { describe('Hello World Elements', () => { - const helloWorldEl = element(by.css('hello-world-el')); - beforeEach(() => browser.get('hello-world.html')); - it('should display "Hello World!"', function () { - expect(helloWorldEl.getText()).toEqual('Hello World!'); + describe('(with default view encapsulation)', () => { + const helloWorldEl = element(by.css('hello-world-el')); + + it('should display "Hello World!"', function () { + expect(helloWorldEl.getText()).toBe('Hello World!'); + }); + + it('should display "Hello Foo!" via name attribute', function () { + const input = element(by.css('input[type=text]')); + input.sendKeys('Foo'); + + // Make tests less flaky on CI by waiting up to 5s for the element text to be updated. + browser.wait(EC.textToBePresentInElement(helloWorldEl, 'Hello Foo!'), 5000); + }); }); - it('should display "Hello Foo!" via name attribute', function () { - const input = element(by.css('input[type=text]')); - input.sendKeys('Foo'); + describe('(with `ShadowDom` view encapsulation)', () => { + const helloWorldShadowEl = element(by.css('hello-world-shadow-el')); + const getShadowDomText = (el: ElementFinder) => + browser.executeScript('return arguments[0].shadowRoot.textContent', el); - // Make tests less flaky on CI by waiting up to 5s for the element text to be updated. - browser.wait(EC.textToBePresentInElement(helloWorldEl, 'Hello Foo!'), 5000); + it('should display "Hello World!"', function () { + expect(getShadowDomText(helloWorldShadowEl)).toBe('Hello World!'); + }); + + it('should display "Hello Foo!" via name attribute', function () { + const input = element(by.css('input[type=text]')); + input.sendKeys('Foo'); + + // Make tests less flaky on CI by waiting up to 5s for the element text to be updated. + browser.wait(async () => await getShadowDomText(helloWorldShadowEl) === 'Hello Foo!', 5000); + }); }); }); }); diff --git a/integration/ng_elements/src/app.ts b/integration/ng_elements/src/app.ts index 689930c4f9..23dbddb997 100644 --- a/integration/ng_elements/src/app.ts +++ b/integration/ng_elements/src/app.ts @@ -11,7 +11,7 @@ import {HelloWorldComponent, HelloWorldShadowComponent, TestCardComponent} from imports: [BrowserModule], }) export class AppModule { - constructor(private injector: Injector) { + constructor(injector: Injector) { customElements.define('hello-world-el', createCustomElement(HelloWorldComponent, {injector})); customElements.define( 'hello-world-shadow-el', createCustomElement(HelloWorldShadowComponent, {injector})); diff --git a/integration/ng_elements/src/elements.ts b/integration/ng_elements/src/elements.ts index 95f17182b4..33276decda 100644 --- a/integration/ng_elements/src/elements.ts +++ b/integration/ng_elements/src/elements.ts @@ -2,7 +2,7 @@ import {Component, Input, ViewEncapsulation} from '@angular/core'; @Component({ selector: 'hello-world-el', - template: `Hello {{name}}!`, + template: 'Hello {{name}}!', }) export class HelloWorldComponent { @Input() name: string = 'World'; @@ -10,14 +10,13 @@ export class HelloWorldComponent { @Component({ selector: 'hello-world-shadow-el', - template: `Hello {{name}}!`, - encapsulation: ViewEncapsulation.ShadowDom + template: 'Hello {{name}}!', + encapsulation: ViewEncapsulation.ShadowDom, }) export class HelloWorldShadowComponent { @Input() name: string = 'World'; } - @Component({ selector: 'test-card', template: ` @@ -29,7 +28,6 @@ export class HelloWorldShadowComponent { `, encapsulation: ViewEncapsulation.ShadowDom, - styles: [] }) export class TestCardComponent { } diff --git a/integration/ng_elements/src/hello-world.html b/integration/ng_elements/src/hello-world.html index 839f0942a9..022a84790a 100644 --- a/integration/ng_elements/src/hello-world.html +++ b/integration/ng_elements/src/hello-world.html @@ -10,8 +10,8 @@ + - diff --git a/integration/ng_elements/src/main.ts b/integration/ng_elements/src/main.ts index e1e39da4b0..f700992f2f 100644 --- a/integration/ng_elements/src/main.ts +++ b/integration/ng_elements/src/main.ts @@ -3,8 +3,11 @@ import {AppModuleNgFactory} from './app.ngfactory'; platformBrowser().bootstrapModuleFactory(AppModuleNgFactory, {ngZone: 'noop'}); -const input = document.querySelector('input'); -const helloWorld = document.querySelector('hello-world-el'); -if(input && helloWorld){ - input.addEventListener('input', () => helloWorld.setAttribute('name', input.value)); -} +const input = document.querySelector('input')!; +const helloWorld = document.querySelector('hello-world-el')!; +const helloWorldShadow = document.querySelector('hello-world-shadow-el')!; + +input.addEventListener('input', () => { + helloWorld.setAttribute('name', input.value); + helloWorldShadow.setAttribute('name', input.value); +});