From 22d03b292e61d888cb51399e0cb3eddfba38d8d4 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Tue, 14 Jan 2020 21:40:48 -0800 Subject: [PATCH 01/14] feat(cdk/testing): Allow custom `querySelectorAll` method This allows the user to drop in a shadow-piercing version of `querySelectorAll` to handle components that use `ViewEncapsulation.ShadowDom` --- package.json | 1 + rollup-globals.bzl | 1 + src/cdk/testing/BUILD.bazel | 10 +++++++- src/cdk/testing/kagekiri.d.ts | 11 +++++++++ .../protractor-harness-environment.ts | 24 ++++++++++++++----- src/cdk/testing/require-config.js | 7 ++++++ .../testbed/testbed-harness-environment.ts | 24 ++++++++++++------- src/cdk/testing/tests/BUILD.bazel | 1 + .../tests/harnesses/main-component-harness.ts | 2 ++ .../testing/tests/test-components-module.ts | 5 ++-- .../testing/tests/test-main-component.html | 7 +++++- src/cdk/testing/tests/test-shadow-boundary.ts | 10 ++++++++ src/cdk/testing/tests/testbed.spec.ts | 22 +++++++++++++++++ test/karma.conf.js | 1 + yarn.lock | 18 +++++++++++++- 15 files changed, 124 insertions(+), 20 deletions(-) create mode 100644 src/cdk/testing/kagekiri.d.ts create mode 100644 src/cdk/testing/require-config.js create mode 100644 src/cdk/testing/tests/test-shadow-boundary.ts diff --git a/package.json b/package.json index be1ab6ea7add..1063d8fdb1a4 100644 --- a/package.json +++ b/package.json @@ -113,6 +113,7 @@ "husky": "^1.3.1", "inquirer": "^6.2.0", "jasmine-core": "^3.5.0", + "kagekiri": "^1.0.16", "karma": "^4.4.1", "karma-browserstack-launcher": "^1.3.0", "karma-chrome-launcher": "^2.2.0", diff --git a/rollup-globals.bzl b/rollup-globals.bzl index 2f0ae3966c3b..32485f6154a3 100644 --- a/rollup-globals.bzl +++ b/rollup-globals.bzl @@ -69,6 +69,7 @@ ROLLUP_GLOBALS = { "@material/top-app-bar": "mdc.topAppBar", # Third-party libraries. + "kagekiri": "kagekiri", "moment": "moment", "protractor": "protractor", "rxjs": "rxjs", diff --git a/src/cdk/testing/BUILD.bazel b/src/cdk/testing/BUILD.bazel index 3967f007d85c..7549ff7b19ab 100644 --- a/src/cdk/testing/BUILD.bazel +++ b/src/cdk/testing/BUILD.bazel @@ -26,7 +26,15 @@ filegroup( ng_web_test_suite( name = "unit_tests", - deps = ["//src/cdk/testing/tests:unit_test_sources"], + # We need to load Kagekiri statically since it is not a named AMD module and needs to + # be manually configured through "require.js" which is used by "karma_web_test_suite". + static_files = [ + "@npm//kagekiri", + ], + deps = [ + ":require-config.js", + "//src/cdk/testing/tests:unit_test_sources" + ], ) e2e_test_suite( diff --git a/src/cdk/testing/kagekiri.d.ts b/src/cdk/testing/kagekiri.d.ts new file mode 100644 index 000000000000..ebc2e72dd119 --- /dev/null +++ b/src/cdk/testing/kagekiri.d.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +declare module 'kagekiri' { + export function querySelectorAll(selector: string, root: Element); +} diff --git a/src/cdk/testing/protractor/protractor-harness-environment.ts b/src/cdk/testing/protractor/protractor-harness-environment.ts index 4ab26a73f1a2..ad54047452a0 100644 --- a/src/cdk/testing/protractor/protractor-harness-environment.ts +++ b/src/cdk/testing/protractor/protractor-harness-environment.ts @@ -7,18 +7,30 @@ */ import {HarnessEnvironment, HarnessLoader, TestElement} from '@angular/cdk/testing'; -import {by, element as protractorElement, ElementFinder} from 'protractor'; +import { + by, + element as protractorElement, + ElementArrayFinder, + ElementFinder, + Locator +} from 'protractor'; import {ProtractorElement} from './protractor-element'; +/** The default query function that respects shadow boundaries. */ +const defaultQueryFn = (selector: string, root: ElementFinder) => root.all(by.css(selector)); + /** A `HarnessEnvironment` implementation for Protractor. */ export class ProtractorHarnessEnvironment extends HarnessEnvironment { - protected constructor(rawRootElement: ElementFinder) { + protected constructor(rawRootElement: ElementFinder, + private _queryFn: (selector: string, root: ElementFinder) => ElementArrayFinder = + defaultQueryFn) { super(rawRootElement); } /** Creates a `HarnessLoader` rooted at the document root. */ - static loader(): HarnessLoader { - return new ProtractorHarnessEnvironment(protractorElement(by.css('body'))); + static loader(queryFn?: (selector: string, root: ElementFinder) => ElementArrayFinder): + HarnessLoader { + return new ProtractorHarnessEnvironment(protractorElement(by.css('body')), queryFn); } async forceStabilize(): Promise {} @@ -37,11 +49,11 @@ export class ProtractorHarnessEnvironment extends HarnessEnvironment { - return new ProtractorHarnessEnvironment(element); + return new ProtractorHarnessEnvironment(element, this._queryFn); } protected async getAllRawElements(selector: string): Promise { - const elementFinderArray = this.rawRootElement.all(by.css(selector)); + const elementFinderArray = this._queryFn(selector, this.rawRootElement); const length = await elementFinderArray.count(); const elements: ElementFinder[] = []; for (let i = 0; i < length; i++) { diff --git a/src/cdk/testing/require-config.js b/src/cdk/testing/require-config.js new file mode 100644 index 000000000000..af84b376e6eb --- /dev/null +++ b/src/cdk/testing/require-config.js @@ -0,0 +1,7 @@ +// Require.js is being used by the karma bazel rules and needs to be configured to properly +// load AMD modules which are not explicitly named in their output bundle. +require.config({ + paths: { + 'kagekiri': '/base/npm/node_modules/kagekiri/dist/kagekiri.umd.min', + } +}); diff --git a/src/cdk/testing/testbed/testbed-harness-environment.ts b/src/cdk/testing/testbed/testbed-harness-environment.ts index c5c3cb4d5aad..1059cdd08568 100644 --- a/src/cdk/testing/testbed/testbed-harness-environment.ts +++ b/src/cdk/testing/testbed/testbed-harness-environment.ts @@ -19,6 +19,8 @@ import {takeWhile} from 'rxjs/operators'; import {TaskState, TaskStateZoneInterceptor} from './task-state-zone-interceptor'; import {UnitTestElement} from './unit-test-element'; +/** The default query function that respects shadow boundaries. */ +const defaultQueryFn = (selector: string, root: Element) => root.querySelectorAll(selector); /** A `HarnessEnvironment` implementation for Angular's Testbed. */ export class TestbedHarnessEnvironment extends HarnessEnvironment { @@ -27,23 +29,26 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { /** Observable that emits whenever the test task state changes. */ private _taskState: Observable; - protected constructor(rawRootElement: Element, private _fixture: ComponentFixture) { + protected constructor(rawRootElement: Element, private _fixture: ComponentFixture, + private _queryFn: (selector: string, root: Element) => ArrayLike = defaultQueryFn) { super(rawRootElement); this._taskState = TaskStateZoneInterceptor.setup(); _fixture.componentRef.onDestroy(() => this._destroyed = true); } /** Creates a `HarnessLoader` rooted at the given fixture's root element. */ - static loader(fixture: ComponentFixture): HarnessLoader { - return new TestbedHarnessEnvironment(fixture.nativeElement, fixture); + static loader(fixture: ComponentFixture, + queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader { + return new TestbedHarnessEnvironment(fixture.nativeElement, fixture, queryFn); } /** * Creates a `HarnessLoader` at the document root. This can be used if harnesses are * located outside of a fixture (e.g. overlays appended to the document body). */ - static documentRootLoader(fixture: ComponentFixture): HarnessLoader { - return new TestbedHarnessEnvironment(document.body, fixture); + static documentRootLoader(fixture: ComponentFixture, + queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader { + return new TestbedHarnessEnvironment(document.body, fixture, queryFn); } /** @@ -53,8 +58,9 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { * of the fixture. */ static async harnessForFixture( - fixture: ComponentFixture, harnessType: ComponentHarnessConstructor): Promise { - const environment = new TestbedHarnessEnvironment(fixture.nativeElement, fixture); + fixture: ComponentFixture, harnessType: ComponentHarnessConstructor, + queryFn?: (selector: string, root: Element) => ArrayLike): Promise { + const environment = new TestbedHarnessEnvironment(fixture.nativeElement, fixture, queryFn); await environment.forceStabilize(); return environment.createComponentHarness(harnessType, fixture.nativeElement); } @@ -95,11 +101,11 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { } protected createEnvironment(element: Element): HarnessEnvironment { - return new TestbedHarnessEnvironment(element, this._fixture); + return new TestbedHarnessEnvironment(element, this._fixture, this._queryFn); } protected async getAllRawElements(selector: string): Promise { await this.forceStabilize(); - return Array.from(this.rawRootElement.querySelectorAll(selector)); + return Array.from(this._queryFn(selector, this.rawRootElement)); } } diff --git a/src/cdk/testing/tests/BUILD.bazel b/src/cdk/testing/tests/BUILD.bazel index f1d088e7c86f..e6064ed9b5a9 100644 --- a/src/cdk/testing/tests/BUILD.bazel +++ b/src/cdk/testing/tests/BUILD.bazel @@ -40,6 +40,7 @@ ng_test_library( "//src/cdk/testing/private", "//src/cdk/testing/testbed", "@npm//@angular/platform-browser", + "@npm//kagekiri", ], ) diff --git a/src/cdk/testing/tests/harnesses/main-component-harness.ts b/src/cdk/testing/tests/harnesses/main-component-harness.ts index 5ccf385b0c20..1b14f99b7885 100644 --- a/src/cdk/testing/tests/harnesses/main-component-harness.ts +++ b/src/cdk/testing/tests/harnesses/main-component-harness.ts @@ -81,6 +81,8 @@ export class MainComponentHarness extends ComponentHarness { this.locatorForAll(SubComponentHarness, SubComponentSpecialHarness); readonly missingElementsAndHarnesses = this.locatorFor('.not-found', SubComponentHarness.with({title: /not found/})); + readonly shadows = this.locatorForAll('.in-the-shadows'); + readonly deepShadow = this.locatorFor('.in-the-shadows + test-shadow-boundary > .in-the-shadows'); private _testTools = this.locatorFor(SubComponentHarness); diff --git a/src/cdk/testing/tests/test-components-module.ts b/src/cdk/testing/tests/test-components-module.ts index 045c8633cbc7..b114789ce038 100644 --- a/src/cdk/testing/tests/test-components-module.ts +++ b/src/cdk/testing/tests/test-components-module.ts @@ -10,11 +10,12 @@ import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {TestMainComponent} from './test-main-component'; +import {TestShadowBoundary} from './test-shadow-boundary'; import {TestSubComponent} from './test-sub-component'; @NgModule({ imports: [CommonModule, FormsModule], - declarations: [TestMainComponent, TestSubComponent], - exports: [TestMainComponent, TestSubComponent] + declarations: [TestMainComponent, TestSubComponent, TestShadowBoundary], + exports: [TestMainComponent, TestSubComponent, TestShadowBoundary] }) export class TestComponentsModule {} diff --git a/src/cdk/testing/tests/test-main-component.html b/src/cdk/testing/tests/test-main-component.html index c57442de2a26..544821fa008d 100644 --- a/src/cdk/testing/tests/test-main-component.html +++ b/src/cdk/testing/tests/test-main-component.html @@ -32,4 +32,9 @@

Main Component

- + +
Shadow 1
+ +
Shadow 2
+
+
diff --git a/src/cdk/testing/tests/test-shadow-boundary.ts b/src/cdk/testing/tests/test-shadow-boundary.ts new file mode 100644 index 000000000000..44088b498ba0 --- /dev/null +++ b/src/cdk/testing/tests/test-shadow-boundary.ts @@ -0,0 +1,10 @@ +import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core'; + +@Component({ + selector: 'test-shadow-boundary', + template: '', + changeDetection: ChangeDetectionStrategy.OnPush, + // tslint:disable-next-line:validate-decorators + encapsulation: ViewEncapsulation.ShadowDom, +}) +export class TestShadowBoundary {} diff --git a/src/cdk/testing/tests/testbed.spec.ts b/src/cdk/testing/tests/testbed.spec.ts index 8caa1b293212..9451a3c83556 100644 --- a/src/cdk/testing/tests/testbed.spec.ts +++ b/src/cdk/testing/tests/testbed.spec.ts @@ -11,6 +11,7 @@ import {MainComponentHarness} from './harnesses/main-component-harness'; import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-component-harness'; import {TestComponentsModule} from './test-components-module'; import {TestMainComponent} from './test-main-component'; +import {querySelectorAll as piercingQuerySelectorAll} from 'kagekiri'; function activeElementText() { return document.activeElement && (document.activeElement as HTMLElement).innerText || ''; @@ -504,6 +505,27 @@ describe('TestbedHarnessEnvironment', () => { } }); }); + + describe('shadow DOM interaction', () => { + it('should not pierce shadow boundary by default', async () => { + const harness = await TestbedHarnessEnvironment + .harnessForFixture(fixture, MainComponentHarness); + expect(await harness.shadows()).toEqual([]); + }); + + it('should pierce shadow boundary when using piercing query', async () => { + const harness = await TestbedHarnessEnvironment + .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); + const shadows = await harness.shadows(); + expect(await Promise.all(shadows.map(el => el.text()))).toEqual(['Shadow 1', 'Shadow 2']); + }); + + it('should allow querying across shadow boundary', async () => { + const harness = await TestbedHarnessEnvironment + .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); + expect(await (await harness.deepShadow()).text()).toBe('Shadow 2'); + }); + }); }); async function checkIsElement(result: ComponentHarness | TestElement, selector?: string) { diff --git a/test/karma.conf.js b/test/karma.conf.js index 3bdb13efd165..bc8006e55515 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -45,6 +45,7 @@ module.exports = config => { watched: false }, {pattern: 'node_modules/@material/*/dist/*', included: false, watched: false}, + {pattern: 'node_modules/kagekiri/**', included: false, watched: false}, // Include all Angular dependencies {pattern: 'node_modules/@angular/**/*', included: false, watched: false}, diff --git a/yarn.lock b/yarn.lock index 7445ff9af27b..9a01566a5ae6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6719,6 +6719,13 @@ jws@^3.0.0, jws@^3.1.4, jws@^3.1.5: jwa "^1.1.5" safe-buffer "^5.0.1" +kagekiri@^1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/kagekiri/-/kagekiri-1.0.16.tgz#b4e0aeb8d57fe2e8d8f84f0d099fe35d21c529ed" + integrity sha512-/F1UiJ1CpRIOqJq8o0z9r6By2Rv2B+rC37fFbcYnKTWJ4JDXmDaEMer8NAm3afWwgRrJgkrQldXy3BL1wToMlg== + dependencies: + postcss-selector-parser nolanlawson/postcss-selector-parser#util-deprecate + karma-browserstack-launcher@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/karma-browserstack-launcher/-/karma-browserstack-launcher-1.3.0.tgz#61fe3d36b1cf10681e40f9d874bf37271fb1c674" @@ -9009,6 +9016,15 @@ postcss-selector-parser@^6.0.2: indexes-of "^1.0.1" uniq "^1.0.1" +"postcss-selector-parser@github:nolanlawson/postcss-selector-parser#util-deprecate": + version "6.0.2" + resolved "https://codeload.github.com/nolanlawson/postcss-selector-parser/tar.gz/75e38f7a7db8d58fb033ab7d24414b55d81e5b4f" + dependencies: + cssesc "^3.0.0" + indexes-of "^1.0.1" + uniq "^1.0.1" + util-deprecate "^1.0.2" + postcss-syntax@^0.36.2: version "0.36.2" resolved "https://registry.yarnpkg.com/postcss-syntax/-/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c" @@ -11830,7 +11846,7 @@ useragent@2.3.0: lru-cache "4.1.x" tmp "0.0.x" -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= From a61a4fdc10315e77d36b6a625e86b53c6d786ed4 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 15 Jan 2020 10:30:34 -0800 Subject: [PATCH 02/14] fix lint and tests --- src/cdk/testing/BUILD.bazel | 2 +- .../testing/protractor/protractor-harness-environment.ts | 8 +------- src/cdk/testing/tests/test-shadow-boundary.ts | 8 ++++++++ tools/public_api_guard/cdk/testing/protractor.d.ts | 4 ++-- tools/public_api_guard/cdk/testing/testbed.d.ts | 8 ++++---- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/cdk/testing/BUILD.bazel b/src/cdk/testing/BUILD.bazel index 7549ff7b19ab..80855ba75c8c 100644 --- a/src/cdk/testing/BUILD.bazel +++ b/src/cdk/testing/BUILD.bazel @@ -33,7 +33,7 @@ ng_web_test_suite( ], deps = [ ":require-config.js", - "//src/cdk/testing/tests:unit_test_sources" + "//src/cdk/testing/tests:unit_test_sources", ], ) diff --git a/src/cdk/testing/protractor/protractor-harness-environment.ts b/src/cdk/testing/protractor/protractor-harness-environment.ts index ad54047452a0..ab0853ee5a76 100644 --- a/src/cdk/testing/protractor/protractor-harness-environment.ts +++ b/src/cdk/testing/protractor/protractor-harness-environment.ts @@ -7,13 +7,7 @@ */ import {HarnessEnvironment, HarnessLoader, TestElement} from '@angular/cdk/testing'; -import { - by, - element as protractorElement, - ElementArrayFinder, - ElementFinder, - Locator -} from 'protractor'; +import {by, element as protractorElement, ElementArrayFinder, ElementFinder} from 'protractor'; import {ProtractorElement} from './protractor-element'; /** The default query function that respects shadow boundaries. */ diff --git a/src/cdk/testing/tests/test-shadow-boundary.ts b/src/cdk/testing/tests/test-shadow-boundary.ts index 44088b498ba0..1333db8d2289 100644 --- a/src/cdk/testing/tests/test-shadow-boundary.ts +++ b/src/cdk/testing/tests/test-shadow-boundary.ts @@ -1,3 +1,11 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/core'; @Component({ diff --git a/tools/public_api_guard/cdk/testing/protractor.d.ts b/tools/public_api_guard/cdk/testing/protractor.d.ts index a1e105b81cf0..cfd4cb022104 100644 --- a/tools/public_api_guard/cdk/testing/protractor.d.ts +++ b/tools/public_api_guard/cdk/testing/protractor.d.ts @@ -19,12 +19,12 @@ export declare class ProtractorElement implements TestElement { } export declare class ProtractorHarnessEnvironment extends HarnessEnvironment { - protected constructor(rawRootElement: ElementFinder); + protected constructor(rawRootElement: ElementFinder, _queryFn?: (selector: string, root: ElementFinder) => ElementArrayFinder); protected createEnvironment(element: ElementFinder): HarnessEnvironment; protected createTestElement(element: ElementFinder): TestElement; forceStabilize(): Promise; protected getAllRawElements(selector: string): Promise; protected getDocumentRoot(): ElementFinder; waitForTasksOutsideAngular(): Promise; - static loader(): HarnessLoader; + static loader(queryFn?: (selector: string, root: ElementFinder) => ElementArrayFinder): HarnessLoader; } diff --git a/tools/public_api_guard/cdk/testing/testbed.d.ts b/tools/public_api_guard/cdk/testing/testbed.d.ts index d2572ad5cf17..41f5eca3abb5 100644 --- a/tools/public_api_guard/cdk/testing/testbed.d.ts +++ b/tools/public_api_guard/cdk/testing/testbed.d.ts @@ -1,14 +1,14 @@ export declare class TestbedHarnessEnvironment extends HarnessEnvironment { - protected constructor(rawRootElement: Element, _fixture: ComponentFixture); + protected constructor(rawRootElement: Element, _fixture: ComponentFixture, _queryFn?: (selector: string, root: Element) => ArrayLike); protected createEnvironment(element: Element): HarnessEnvironment; protected createTestElement(element: Element): TestElement; forceStabilize(): Promise; protected getAllRawElements(selector: string): Promise; protected getDocumentRoot(): Element; waitForTasksOutsideAngular(): Promise; - static documentRootLoader(fixture: ComponentFixture): HarnessLoader; - static harnessForFixture(fixture: ComponentFixture, harnessType: ComponentHarnessConstructor): Promise; - static loader(fixture: ComponentFixture): HarnessLoader; + static documentRootLoader(fixture: ComponentFixture, queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader; + static harnessForFixture(fixture: ComponentFixture, harnessType: ComponentHarnessConstructor, queryFn?: (selector: string, root: Element) => ArrayLike): Promise; + static loader(fixture: ComponentFixture, queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader; } export declare class UnitTestElement implements TestElement { From 1f085e6f906352dd82f6966ae006159d9ed8b387 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 15 Jan 2020 18:04:25 -0800 Subject: [PATCH 03/14] exclude shadow dom tests on browsers that don't support it --- src/cdk/testing/tests/BUILD.bazel | 2 + .../testing/tests/test-main-component.html | 2 +- src/cdk/testing/tests/test-main-component.ts | 2 + src/cdk/testing/tests/testbed.spec.ts | 43 ++++++++++--------- yarn.lock | 2 +- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/cdk/testing/tests/BUILD.bazel b/src/cdk/testing/tests/BUILD.bazel index e6064ed9b5a9..a0cf73ecff4b 100644 --- a/src/cdk/testing/tests/BUILD.bazel +++ b/src/cdk/testing/tests/BUILD.bazel @@ -15,6 +15,7 @@ ng_module( assets = glob(["**/*.html"]), deps = [ "//src/cdk/keycodes", + "//src/cdk/platform", "@npm//@angular/forms", ], ) @@ -36,6 +37,7 @@ ng_test_library( deps = [ ":test_components", ":test_harnesses", + "//src/cdk/platform", "//src/cdk/testing", "//src/cdk/testing/private", "//src/cdk/testing/testbed", diff --git a/src/cdk/testing/tests/test-main-component.html b/src/cdk/testing/tests/test-main-component.html index 544821fa008d..a220c27dddcb 100644 --- a/src/cdk/testing/tests/test-main-component.html +++ b/src/cdk/testing/tests/test-main-component.html @@ -32,7 +32,7 @@

Main Component

- +
Shadow 1
Shadow 2
diff --git a/src/cdk/testing/tests/test-main-component.ts b/src/cdk/testing/tests/test-main-component.ts index 32c18182b0af..2c4d9fd551bb 100644 --- a/src/cdk/testing/tests/test-main-component.ts +++ b/src/cdk/testing/tests/test-main-component.ts @@ -7,6 +7,7 @@ */ import {ENTER} from '@angular/cdk/keycodes'; +import {_supportsShadowDom} from '@angular/cdk/platform'; import { ChangeDetectionStrategy, ChangeDetectorRef, @@ -42,6 +43,7 @@ export class TestMainComponent implements OnDestroy { specialKey = ''; relativeX = 0; relativeY = 0; + _shadowDomSupported = _supportsShadowDom(); @ViewChild('clickTestElement') clickTestElement: ElementRef; @ViewChild('taskStateResult') taskStateResultElement: ElementRef; diff --git a/src/cdk/testing/tests/testbed.spec.ts b/src/cdk/testing/tests/testbed.spec.ts index 9451a3c83556..8626e6edf061 100644 --- a/src/cdk/testing/tests/testbed.spec.ts +++ b/src/cdk/testing/tests/testbed.spec.ts @@ -1,3 +1,4 @@ +import {_supportsShadowDom} from '@angular/cdk/platform'; import { ComponentHarness, ComponentHarnessConstructor, @@ -6,12 +7,12 @@ import { } from '@angular/cdk/testing'; import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; import {async, ComponentFixture, fakeAsync, TestBed} from '@angular/core/testing'; +import {querySelectorAll as piercingQuerySelectorAll} from 'kagekiri'; import {FakeOverlayHarness} from './harnesses/fake-overlay-harness'; import {MainComponentHarness} from './harnesses/main-component-harness'; import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-component-harness'; import {TestComponentsModule} from './test-components-module'; import {TestMainComponent} from './test-main-component'; -import {querySelectorAll as piercingQuerySelectorAll} from 'kagekiri'; function activeElementText() { return document.activeElement && (document.activeElement as HTMLElement).innerText || ''; @@ -506,26 +507,28 @@ describe('TestbedHarnessEnvironment', () => { }); }); - describe('shadow DOM interaction', () => { - it('should not pierce shadow boundary by default', async () => { - const harness = await TestbedHarnessEnvironment - .harnessForFixture(fixture, MainComponentHarness); - expect(await harness.shadows()).toEqual([]); - }); - - it('should pierce shadow boundary when using piercing query', async () => { - const harness = await TestbedHarnessEnvironment - .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); - const shadows = await harness.shadows(); - expect(await Promise.all(shadows.map(el => el.text()))).toEqual(['Shadow 1', 'Shadow 2']); + if (_supportsShadowDom()) { + describe('shadow DOM interaction', () => { + it('should not pierce shadow boundary by default', async () => { + const harness = await TestbedHarnessEnvironment + .harnessForFixture(fixture, MainComponentHarness); + expect(await harness.shadows()).toEqual([]); + }); + + it('should pierce shadow boundary when using piercing query', async () => { + const harness = await TestbedHarnessEnvironment + .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); + const shadows = await harness.shadows(); + expect(await Promise.all(shadows.map(el => el.text()))).toEqual(['Shadow 1', 'Shadow 2']); + }); + + it('should allow querying across shadow boundary', async () => { + const harness = await TestbedHarnessEnvironment + .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); + expect(await (await harness.deepShadow()).text()).toBe('Shadow 2'); + }); }); - - it('should allow querying across shadow boundary', async () => { - const harness = await TestbedHarnessEnvironment - .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); - expect(await (await harness.deepShadow()).text()).toBe('Shadow 2'); - }); - }); + } }); async function checkIsElement(result: ComponentHarness | TestElement, selector?: string) { diff --git a/yarn.lock b/yarn.lock index 9a01566a5ae6..3102e3c2a865 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9016,7 +9016,7 @@ postcss-selector-parser@^6.0.2: indexes-of "^1.0.1" uniq "^1.0.1" -"postcss-selector-parser@github:nolanlawson/postcss-selector-parser#util-deprecate": +postcss-selector-parser@nolanlawson/postcss-selector-parser#util-deprecate: version "6.0.2" resolved "https://codeload.github.com/nolanlawson/postcss-selector-parser/tar.gz/75e38f7a7db8d58fb033ab7d24414b55d81e5b4f" dependencies: From dffaf234722ac9588de968d9f46eae3b2029d125 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 16 Jan 2020 15:50:29 -0800 Subject: [PATCH 04/14] WIP: trying to fix import paths for gulp --- src/cdk/testing/tests/testbed.spec.ts | 6 ++++-- src/e2e-app/devserver-configure.js | 1 + tools/system-config-tmpl.js | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cdk/testing/tests/testbed.spec.ts b/src/cdk/testing/tests/testbed.spec.ts index 8626e6edf061..56bbaa08f23a 100644 --- a/src/cdk/testing/tests/testbed.spec.ts +++ b/src/cdk/testing/tests/testbed.spec.ts @@ -1,4 +1,4 @@ -import {_supportsShadowDom} from '@angular/cdk/platform'; +import {_supportsShadowDom, Platform} from '@angular/cdk/platform'; import { ComponentHarness, ComponentHarnessConstructor, @@ -507,7 +507,9 @@ describe('TestbedHarnessEnvironment', () => { }); }); - if (_supportsShadowDom()) { + const platform = new Platform(); + // Safari only has parial shadow DOM support (https://caniuse.com/#feat=shadowdomv1) + if (_supportsShadowDom() && !platform.SAFARI) { describe('shadow DOM interaction', () => { it('should not pierce shadow boundary by default', async () => { const harness = await TestbedHarnessEnvironment diff --git a/src/e2e-app/devserver-configure.js b/src/e2e-app/devserver-configure.js index 97f65a73e620..0a54272655d1 100644 --- a/src/e2e-app/devserver-configure.js +++ b/src/e2e-app/devserver-configure.js @@ -3,6 +3,7 @@ require.config({ paths: { 'moment': 'moment/min/moment.min', + 'kagekiri': 'kagekiri/dist/kagekiri.umd.min.js', // Support for lazy-loading of component examples. '@angular/components-examples': 'angular_material/src/components-examples', diff --git a/tools/system-config-tmpl.js b/tools/system-config-tmpl.js index 33dbe96511f7..6e8cdae10997 100644 --- a/tools/system-config-tmpl.js +++ b/tools/system-config-tmpl.js @@ -31,6 +31,7 @@ var nodeModulesPath = '$NODE_MODULES_BASE_PATH'; var pathMapping = { 'tslib': 'node:tslib/tslib.js', 'moment': 'node:moment/min/moment-with-locales.min.js', + 'kagekiri': 'node:kagekiri/dist/kagekiri.umd.min.js', 'rxjs': 'node:rxjs/bundles/rxjs.umd.min.js', 'rxjs/operators': 'tools/system-rxjs-operators.js', From a2a27c37b7d430a971c53428348fcb85a2bb9c58 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 24 Jan 2020 10:29:57 -0800 Subject: [PATCH 05/14] stop using ng-content --- .../tests/harnesses/main-component-harness.ts | 3 ++- src/cdk/testing/tests/test-components-module.ts | 6 +++--- src/cdk/testing/tests/test-main-component.html | 7 +------ src/cdk/testing/tests/test-shadow-boundary.ts | 14 +++++++++++++- src/cdk/testing/tests/testbed.spec.ts | 6 ++---- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/cdk/testing/tests/harnesses/main-component-harness.ts b/src/cdk/testing/tests/harnesses/main-component-harness.ts index 1b14f99b7885..0c0f9e0f35b7 100644 --- a/src/cdk/testing/tests/harnesses/main-component-harness.ts +++ b/src/cdk/testing/tests/harnesses/main-component-harness.ts @@ -82,7 +82,8 @@ export class MainComponentHarness extends ComponentHarness { readonly missingElementsAndHarnesses = this.locatorFor('.not-found', SubComponentHarness.with({title: /not found/})); readonly shadows = this.locatorForAll('.in-the-shadows'); - readonly deepShadow = this.locatorFor('.in-the-shadows + test-shadow-boundary > .in-the-shadows'); + readonly deepShadow = this.locatorFor( + '.in-the-shadows + test-sub-shadow-boundary > .in-the-shadows'); private _testTools = this.locatorFor(SubComponentHarness); diff --git a/src/cdk/testing/tests/test-components-module.ts b/src/cdk/testing/tests/test-components-module.ts index b114789ce038..10cef6eeaad7 100644 --- a/src/cdk/testing/tests/test-components-module.ts +++ b/src/cdk/testing/tests/test-components-module.ts @@ -10,12 +10,12 @@ import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; import {FormsModule} from '@angular/forms'; import {TestMainComponent} from './test-main-component'; -import {TestShadowBoundary} from './test-shadow-boundary'; +import {TestShadowBoundary, TestSubShadowBoundary} from './test-shadow-boundary'; import {TestSubComponent} from './test-sub-component'; @NgModule({ imports: [CommonModule, FormsModule], - declarations: [TestMainComponent, TestSubComponent, TestShadowBoundary], - exports: [TestMainComponent, TestSubComponent, TestShadowBoundary] + declarations: [TestMainComponent, TestSubComponent, TestShadowBoundary, TestSubShadowBoundary], + exports: [TestMainComponent, TestSubComponent, TestShadowBoundary, TestSubShadowBoundary] }) export class TestComponentsModule {} diff --git a/src/cdk/testing/tests/test-main-component.html b/src/cdk/testing/tests/test-main-component.html index a220c27dddcb..99998b6b0670 100644 --- a/src/cdk/testing/tests/test-main-component.html +++ b/src/cdk/testing/tests/test-main-component.html @@ -32,9 +32,4 @@

Main Component

- -
Shadow 1
- -
Shadow 2
-
-
+ diff --git a/src/cdk/testing/tests/test-shadow-boundary.ts b/src/cdk/testing/tests/test-shadow-boundary.ts index 1333db8d2289..ee7cb1d0616d 100644 --- a/src/cdk/testing/tests/test-shadow-boundary.ts +++ b/src/cdk/testing/tests/test-shadow-boundary.ts @@ -10,9 +10,21 @@ import {ChangeDetectionStrategy, Component, ViewEncapsulation} from '@angular/co @Component({ selector: 'test-shadow-boundary', - template: '', + template: ` +
Shadow 1
+ + `, changeDetection: ChangeDetectionStrategy.OnPush, // tslint:disable-next-line:validate-decorators encapsulation: ViewEncapsulation.ShadowDom, }) export class TestShadowBoundary {} + +@Component({ + selector: 'test-sub-shadow-boundary', + template: '
Shadow 2
', + changeDetection: ChangeDetectionStrategy.OnPush, + // tslint:disable-next-line:validate-decorators + encapsulation: ViewEncapsulation.ShadowDom, +}) +export class TestSubShadowBoundary {} diff --git a/src/cdk/testing/tests/testbed.spec.ts b/src/cdk/testing/tests/testbed.spec.ts index 56bbaa08f23a..8626e6edf061 100644 --- a/src/cdk/testing/tests/testbed.spec.ts +++ b/src/cdk/testing/tests/testbed.spec.ts @@ -1,4 +1,4 @@ -import {_supportsShadowDom, Platform} from '@angular/cdk/platform'; +import {_supportsShadowDom} from '@angular/cdk/platform'; import { ComponentHarness, ComponentHarnessConstructor, @@ -507,9 +507,7 @@ describe('TestbedHarnessEnvironment', () => { }); }); - const platform = new Platform(); - // Safari only has parial shadow DOM support (https://caniuse.com/#feat=shadowdomv1) - if (_supportsShadowDom() && !platform.SAFARI) { + if (_supportsShadowDom()) { describe('shadow DOM interaction', () => { it('should not pierce shadow boundary by default', async () => { const harness = await TestbedHarnessEnvironment From 8062fe7f59282540ac45d23fe425627bb4b96016 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 24 Jan 2020 14:52:34 -0800 Subject: [PATCH 06/14] WIP: attempt to get protractor working --- src/cdk/testing/tests/BUILD.bazel | 1 + src/cdk/testing/tests/protractor.e2e.spec.ts | 29 +++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/cdk/testing/tests/BUILD.bazel b/src/cdk/testing/tests/BUILD.bazel index a0cf73ecff4b..22a1a9d2e4d4 100644 --- a/src/cdk/testing/tests/BUILD.bazel +++ b/src/cdk/testing/tests/BUILD.bazel @@ -54,5 +54,6 @@ ng_e2e_test_library( "//src/cdk/testing", "//src/cdk/testing/private", "//src/cdk/testing/protractor", + "@npm//kagekiri", ], ) diff --git a/src/cdk/testing/tests/protractor.e2e.spec.ts b/src/cdk/testing/tests/protractor.e2e.spec.ts index 15bb9708f75f..16468b0a4b98 100644 --- a/src/cdk/testing/tests/protractor.e2e.spec.ts +++ b/src/cdk/testing/tests/protractor.e2e.spec.ts @@ -5,9 +5,15 @@ import { TestElement } from '@angular/cdk/testing'; import {ProtractorHarnessEnvironment} from '@angular/cdk/testing/protractor'; -import {browser} from 'protractor'; +import {browser, by, ElementFinder} from 'protractor'; import {MainComponentHarness} from './harnesses/main-component-harness'; import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-component-harness'; +import {querySelectorAll as piercingQuerySelectorAll} from 'kagekiri'; + +const piercingQueryFn = + (selector: string, root: ElementFinder) => root.all(by.js(function(this: any) { + piercingQuerySelectorAll(selector, this); + })); describe('ProtractorHarnessEnvironment', () => { beforeEach(async () => { @@ -460,6 +466,27 @@ describe('ProtractorHarnessEnvironment', () => { } }); }); + + describe('shadow DOM interaction', () => { + it('should not pierce shadow boundary by default', async () => { + const harness = await ProtractorHarnessEnvironment.loader(piercingQueryFn) + .getHarness(MainComponentHarness); + expect(await harness.shadows()).toEqual([]); + }); + + it('should pierce shadow boundary when using piercing query', async () => { + const harness = await ProtractorHarnessEnvironment.loader(piercingQueryFn) + .getHarness(MainComponentHarness); + const shadows = await harness.shadows(); + expect(await Promise.all(shadows.map(el => el.text()))).toEqual(['Shadow 1', 'Shadow 2']); + }); + + it('should allow querying across shadow boundary', async () => { + const harness = await ProtractorHarnessEnvironment.loader(piercingQueryFn) + .getHarness(MainComponentHarness); + expect(await (await harness.deepShadow()).text()).toBe('Shadow 2'); + }); + }); }); async function checkIsElement(result: ComponentHarness | TestElement, selector?: string) { From 965a9a9dffdd8782c21b6310aacfcba55f53df3b Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Tue, 28 Jan 2020 12:13:04 -0800 Subject: [PATCH 07/14] make protractor tests work --- package.json | 2 +- src/cdk/testing/kagekiri.d.ts | 2 +- .../protractor-harness-environment.ts | 6 ++--- src/cdk/testing/tests/BUILD.bazel | 1 - src/cdk/testing/tests/protractor.e2e.spec.ts | 16 +++++++----- src/e2e-app/BUILD.bazel | 1 + src/e2e-app/index.html | 1 + yarn.lock | 26 ++++--------------- 8 files changed, 21 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 1063d8fdb1a4..5b1e29d2e9ee 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "husky": "^1.3.1", "inquirer": "^6.2.0", "jasmine-core": "^3.5.0", - "kagekiri": "^1.0.16", + "kagekiri": "^1.0.18", "karma": "^4.4.1", "karma-browserstack-launcher": "^1.3.0", "karma-chrome-launcher": "^2.2.0", diff --git a/src/cdk/testing/kagekiri.d.ts b/src/cdk/testing/kagekiri.d.ts index ebc2e72dd119..336a0a181446 100644 --- a/src/cdk/testing/kagekiri.d.ts +++ b/src/cdk/testing/kagekiri.d.ts @@ -7,5 +7,5 @@ */ declare module 'kagekiri' { - export function querySelectorAll(selector: string, root: Element); + export function querySelectorAll(selector: string, root: Element): NodeListOf; } diff --git a/src/cdk/testing/protractor/protractor-harness-environment.ts b/src/cdk/testing/protractor/protractor-harness-environment.ts index ab0853ee5a76..a1df4887413e 100644 --- a/src/cdk/testing/protractor/protractor-harness-environment.ts +++ b/src/cdk/testing/protractor/protractor-harness-environment.ts @@ -47,11 +47,11 @@ export class ProtractorHarnessEnvironment extends HarnessEnvironment { - const elementFinderArray = this._queryFn(selector, this.rawRootElement); - const length = await elementFinderArray.count(); + const elementArrayFinder = this._queryFn(selector, this.rawRootElement); + const length = await elementArrayFinder.count(); const elements: ElementFinder[] = []; for (let i = 0; i < length; i++) { - elements.push(elementFinderArray.get(i)); + elements.push(elementArrayFinder.get(i)); } return elements; } diff --git a/src/cdk/testing/tests/BUILD.bazel b/src/cdk/testing/tests/BUILD.bazel index 22a1a9d2e4d4..a0cf73ecff4b 100644 --- a/src/cdk/testing/tests/BUILD.bazel +++ b/src/cdk/testing/tests/BUILD.bazel @@ -54,6 +54,5 @@ ng_e2e_test_library( "//src/cdk/testing", "//src/cdk/testing/private", "//src/cdk/testing/protractor", - "@npm//kagekiri", ], ) diff --git a/src/cdk/testing/tests/protractor.e2e.spec.ts b/src/cdk/testing/tests/protractor.e2e.spec.ts index 16468b0a4b98..c54822ebd7b1 100644 --- a/src/cdk/testing/tests/protractor.e2e.spec.ts +++ b/src/cdk/testing/tests/protractor.e2e.spec.ts @@ -5,15 +5,17 @@ import { TestElement } from '@angular/cdk/testing'; import {ProtractorHarnessEnvironment} from '@angular/cdk/testing/protractor'; -import {browser, by, ElementFinder} from 'protractor'; +import {browser, by, element as protractorElement, ElementFinder} from 'protractor'; import {MainComponentHarness} from './harnesses/main-component-harness'; import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-component-harness'; -import {querySelectorAll as piercingQuerySelectorAll} from 'kagekiri'; -const piercingQueryFn = - (selector: string, root: ElementFinder) => root.all(by.js(function(this: any) { - piercingQuerySelectorAll(selector, this); - })); +// TODO: is there some better way to do this? +declare const kagekiri: { + querySelectorAll: (selector: string, root: Element) => NodeListOf; +}; + +const piercingQueryFn = (selector: string, root: ElementFinder) => protractorElement.all(by.js( + (s: string, r: Element) => kagekiri.querySelectorAll(s, r), selector, root.getWebElement())); describe('ProtractorHarnessEnvironment', () => { beforeEach(async () => { @@ -469,7 +471,7 @@ describe('ProtractorHarnessEnvironment', () => { describe('shadow DOM interaction', () => { it('should not pierce shadow boundary by default', async () => { - const harness = await ProtractorHarnessEnvironment.loader(piercingQueryFn) + const harness = await ProtractorHarnessEnvironment.loader() .getHarness(MainComponentHarness); expect(await harness.shadows()).toEqual([]); }); diff --git a/src/e2e-app/BUILD.bazel b/src/e2e-app/BUILD.bazel index 12e22b114f1d..184cd887aa64 100644 --- a/src/e2e-app/BUILD.bazel +++ b/src/e2e-app/BUILD.bazel @@ -102,6 +102,7 @@ ts_devserver( static_files = [ "@npm//zone.js", "@npm//core-js", + "@npm//kagekiri", "@npm//material-components-web", "@npm//moment", "@npm//@webcomponents/custom-elements", diff --git a/src/e2e-app/index.html b/src/e2e-app/index.html index 79483f0eea7f..0c0c2844f426 100644 --- a/src/e2e-app/index.html +++ b/src/e2e-app/index.html @@ -29,6 +29,7 @@ + diff --git a/yarn.lock b/yarn.lock index 3102e3c2a865..57e752a9985b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3500,11 +3500,6 @@ cssesc@^0.1.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - csv-streamify@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/csv-streamify/-/csv-streamify-3.0.4.tgz#4cb614c57e3f299cca17b63fdcb4ad167777f47a" @@ -6719,12 +6714,10 @@ jws@^3.0.0, jws@^3.1.4, jws@^3.1.5: jwa "^1.1.5" safe-buffer "^5.0.1" -kagekiri@^1.0.16: - version "1.0.16" - resolved "https://registry.yarnpkg.com/kagekiri/-/kagekiri-1.0.16.tgz#b4e0aeb8d57fe2e8d8f84f0d099fe35d21c529ed" - integrity sha512-/F1UiJ1CpRIOqJq8o0z9r6By2Rv2B+rC37fFbcYnKTWJ4JDXmDaEMer8NAm3afWwgRrJgkrQldXy3BL1wToMlg== - dependencies: - postcss-selector-parser nolanlawson/postcss-selector-parser#util-deprecate +kagekiri@^1.0.18: + version "1.0.18" + resolved "https://registry.yarnpkg.com/kagekiri/-/kagekiri-1.0.18.tgz#4400714f37d79e7ec80c99aa5a0a59f729c1a6a7" + integrity sha512-J0dcWXcdzMDBOm3YE5sljkPfAHenv9zELJhjlfo/mxe98CtaaIXbC9JIjOfLk8m4B9hiATmkm5vBaBPrOOSbAQ== karma-browserstack-launcher@^1.3.0: version "1.3.0" @@ -9016,15 +9009,6 @@ postcss-selector-parser@^6.0.2: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@nolanlawson/postcss-selector-parser#util-deprecate: - version "6.0.2" - resolved "https://codeload.github.com/nolanlawson/postcss-selector-parser/tar.gz/75e38f7a7db8d58fb033ab7d24414b55d81e5b4f" - dependencies: - cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" - util-deprecate "^1.0.2" - postcss-syntax@^0.36.2: version "0.36.2" resolved "https://registry.yarnpkg.com/postcss-syntax/-/postcss-syntax-0.36.2.tgz#f08578c7d95834574e5593a82dfbfa8afae3b51c" @@ -11846,7 +11830,7 @@ useragent@2.3.0: lru-cache "4.1.x" tmp "0.0.x" -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= From db046101e384e3d04b6e16ab27c451f5027e8598 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Wed, 29 Jan 2020 08:50:11 -0800 Subject: [PATCH 08/14] address comments --- .../protractor-harness-environment.ts | 30 ++++++++++----- .../testbed/testbed-harness-environment.ts | 37 +++++++++++++------ src/cdk/testing/tests/protractor.e2e.spec.ts | 7 ++-- src/cdk/testing/tests/testbed.spec.ts | 4 +- 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/cdk/testing/protractor/protractor-harness-environment.ts b/src/cdk/testing/protractor/protractor-harness-environment.ts index a1df4887413e..1ff79296ddd8 100644 --- a/src/cdk/testing/protractor/protractor-harness-environment.ts +++ b/src/cdk/testing/protractor/protractor-harness-environment.ts @@ -10,21 +10,31 @@ import {HarnessEnvironment, HarnessLoader, TestElement} from '@angular/cdk/testi import {by, element as protractorElement, ElementArrayFinder, ElementFinder} from 'protractor'; import {ProtractorElement} from './protractor-element'; -/** The default query function that respects shadow boundaries. */ -const defaultQueryFn = (selector: string, root: ElementFinder) => root.all(by.css(selector)); +/** Options to configure the environment. */ +export interface ProtractorHarnessEnvironmentOptions { + /** The query function used to find DOM elements. */ + queryFn: (selector: string, root: ElementFinder) => ElementArrayFinder; +} + +/** The default environment options. */ +const defaultEnvironmentOptions: ProtractorHarnessEnvironmentOptions = { + queryFn: (selector: string, root: ElementFinder) => root.all(by.css(selector)) +}; /** A `HarnessEnvironment` implementation for Protractor. */ export class ProtractorHarnessEnvironment extends HarnessEnvironment { - protected constructor(rawRootElement: ElementFinder, - private _queryFn: (selector: string, root: ElementFinder) => ElementArrayFinder = - defaultQueryFn) { + /** The options for this environment. */ + private _options: ProtractorHarnessEnvironmentOptions; + + protected constructor( + rawRootElement: ElementFinder, options?: ProtractorHarnessEnvironmentOptions) { super(rawRootElement); + this._options = {...defaultEnvironmentOptions, ...options}; } /** Creates a `HarnessLoader` rooted at the document root. */ - static loader(queryFn?: (selector: string, root: ElementFinder) => ElementArrayFinder): - HarnessLoader { - return new ProtractorHarnessEnvironment(protractorElement(by.css('body')), queryFn); + static loader(options?: ProtractorHarnessEnvironmentOptions): HarnessLoader { + return new ProtractorHarnessEnvironment(protractorElement(by.css('body')), options); } async forceStabilize(): Promise {} @@ -43,11 +53,11 @@ export class ProtractorHarnessEnvironment extends HarnessEnvironment { - return new ProtractorHarnessEnvironment(element, this._queryFn); + return new ProtractorHarnessEnvironment(element, this._options); } protected async getAllRawElements(selector: string): Promise { - const elementArrayFinder = this._queryFn(selector, this.rawRootElement); + const elementArrayFinder = this._options.queryFn(selector, this.rawRootElement); const length = await elementArrayFinder.count(); const elements: ElementFinder[] = []; for (let i = 0; i < length; i++) { diff --git a/src/cdk/testing/testbed/testbed-harness-environment.ts b/src/cdk/testing/testbed/testbed-harness-environment.ts index 1059cdd08568..43ef85ccac51 100644 --- a/src/cdk/testing/testbed/testbed-harness-environment.ts +++ b/src/cdk/testing/testbed/testbed-harness-environment.ts @@ -19,27 +19,40 @@ import {takeWhile} from 'rxjs/operators'; import {TaskState, TaskStateZoneInterceptor} from './task-state-zone-interceptor'; import {UnitTestElement} from './unit-test-element'; -/** The default query function that respects shadow boundaries. */ -const defaultQueryFn = (selector: string, root: Element) => root.querySelectorAll(selector); +/** Options to configure the environment. */ +export interface TestbedHarnessEnvironmentOptions { + /** The query function used to find DOM elements. */ + queryFn: (selector: string, root: Element) => ArrayLike; +} + +/** The default environment options. */ +const defaultEnvironmentOptions: TestbedHarnessEnvironmentOptions = { + queryFn: (selector: string, root: Element) => root.querySelectorAll(selector) +}; /** A `HarnessEnvironment` implementation for Angular's Testbed. */ export class TestbedHarnessEnvironment extends HarnessEnvironment { + /** Whether the environment has been destroyed. */ private _destroyed = false; /** Observable that emits whenever the test task state changes. */ private _taskState: Observable; + /** The options for this environment. */ + private _options: TestbedHarnessEnvironmentOptions; + protected constructor(rawRootElement: Element, private _fixture: ComponentFixture, - private _queryFn: (selector: string, root: Element) => ArrayLike = defaultQueryFn) { + options?: TestbedHarnessEnvironmentOptions) { super(rawRootElement); + this._options = {...defaultEnvironmentOptions, ...options}; this._taskState = TaskStateZoneInterceptor.setup(); _fixture.componentRef.onDestroy(() => this._destroyed = true); } /** Creates a `HarnessLoader` rooted at the given fixture's root element. */ - static loader(fixture: ComponentFixture, - queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader { - return new TestbedHarnessEnvironment(fixture.nativeElement, fixture, queryFn); + static loader(fixture: ComponentFixture, options?: TestbedHarnessEnvironmentOptions): + HarnessLoader { + return new TestbedHarnessEnvironment(fixture.nativeElement, fixture, options); } /** @@ -47,8 +60,8 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { * located outside of a fixture (e.g. overlays appended to the document body). */ static documentRootLoader(fixture: ComponentFixture, - queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader { - return new TestbedHarnessEnvironment(document.body, fixture, queryFn); + options?: TestbedHarnessEnvironmentOptions): HarnessLoader { + return new TestbedHarnessEnvironment(document.body, fixture, options); } /** @@ -59,8 +72,8 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { */ static async harnessForFixture( fixture: ComponentFixture, harnessType: ComponentHarnessConstructor, - queryFn?: (selector: string, root: Element) => ArrayLike): Promise { - const environment = new TestbedHarnessEnvironment(fixture.nativeElement, fixture, queryFn); + options?: TestbedHarnessEnvironmentOptions): Promise { + const environment = new TestbedHarnessEnvironment(fixture.nativeElement, fixture, options); await environment.forceStabilize(); return environment.createComponentHarness(harnessType, fixture.nativeElement); } @@ -101,11 +114,11 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment { } protected createEnvironment(element: Element): HarnessEnvironment { - return new TestbedHarnessEnvironment(element, this._fixture, this._queryFn); + return new TestbedHarnessEnvironment(element, this._fixture, this._options); } protected async getAllRawElements(selector: string): Promise { await this.forceStabilize(); - return Array.from(this._queryFn(selector, this.rawRootElement)); + return Array.from(this._options.queryFn(selector, this.rawRootElement)); } } diff --git a/src/cdk/testing/tests/protractor.e2e.spec.ts b/src/cdk/testing/tests/protractor.e2e.spec.ts index c54822ebd7b1..d3b6dab0a7c2 100644 --- a/src/cdk/testing/tests/protractor.e2e.spec.ts +++ b/src/cdk/testing/tests/protractor.e2e.spec.ts @@ -9,7 +9,8 @@ import {browser, by, element as protractorElement, ElementFinder} from 'protract import {MainComponentHarness} from './harnesses/main-component-harness'; import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-component-harness'; -// TODO: is there some better way to do this? +// Kagekiri is available globally in the browser. We declare it here so we can use it in the +// browser-side script passed to `by.js`. declare const kagekiri: { querySelectorAll: (selector: string, root: Element) => NodeListOf; }; @@ -477,14 +478,14 @@ describe('ProtractorHarnessEnvironment', () => { }); it('should pierce shadow boundary when using piercing query', async () => { - const harness = await ProtractorHarnessEnvironment.loader(piercingQueryFn) + const harness = await ProtractorHarnessEnvironment.loader({queryFn: piercingQueryFn}) .getHarness(MainComponentHarness); const shadows = await harness.shadows(); expect(await Promise.all(shadows.map(el => el.text()))).toEqual(['Shadow 1', 'Shadow 2']); }); it('should allow querying across shadow boundary', async () => { - const harness = await ProtractorHarnessEnvironment.loader(piercingQueryFn) + const harness = await ProtractorHarnessEnvironment.loader({queryFn: piercingQueryFn}) .getHarness(MainComponentHarness); expect(await (await harness.deepShadow()).text()).toBe('Shadow 2'); }); diff --git a/src/cdk/testing/tests/testbed.spec.ts b/src/cdk/testing/tests/testbed.spec.ts index 8626e6edf061..59854ff67cbe 100644 --- a/src/cdk/testing/tests/testbed.spec.ts +++ b/src/cdk/testing/tests/testbed.spec.ts @@ -517,14 +517,14 @@ describe('TestbedHarnessEnvironment', () => { it('should pierce shadow boundary when using piercing query', async () => { const harness = await TestbedHarnessEnvironment - .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); + .harnessForFixture(fixture, MainComponentHarness, {queryFn: piercingQuerySelectorAll}); const shadows = await harness.shadows(); expect(await Promise.all(shadows.map(el => el.text()))).toEqual(['Shadow 1', 'Shadow 2']); }); it('should allow querying across shadow boundary', async () => { const harness = await TestbedHarnessEnvironment - .harnessForFixture(fixture, MainComponentHarness, piercingQuerySelectorAll); + .harnessForFixture(fixture, MainComponentHarness, {queryFn: piercingQuerySelectorAll}); expect(await (await harness.deepShadow()).text()).toBe('Shadow 2'); }); }); From c825190f054f3ceede38b4cc1d1fef450a5043be Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 30 Jan 2020 12:46:04 -0800 Subject: [PATCH 09/14] address feedback --- src/cdk/testing/kagekiri.d.ts | 2 ++ src/cdk/testing/tests/protractor.e2e.spec.ts | 2 ++ src/e2e-app/devserver-configure.js | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cdk/testing/kagekiri.d.ts b/src/cdk/testing/kagekiri.d.ts index 336a0a181446..bfa43c5ae493 100644 --- a/src/cdk/testing/kagekiri.d.ts +++ b/src/cdk/testing/kagekiri.d.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ +// Note: kagekiri is a dev dependency that is used only in our tests to test using a custom +// querySelector function. Do not use this in published code. declare module 'kagekiri' { export function querySelectorAll(selector: string, root: Element): NodeListOf; } diff --git a/src/cdk/testing/tests/protractor.e2e.spec.ts b/src/cdk/testing/tests/protractor.e2e.spec.ts index d3b6dab0a7c2..0395a2863c78 100644 --- a/src/cdk/testing/tests/protractor.e2e.spec.ts +++ b/src/cdk/testing/tests/protractor.e2e.spec.ts @@ -11,6 +11,8 @@ import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-c // Kagekiri is available globally in the browser. We declare it here so we can use it in the // browser-side script passed to `by.js`. +// TODO(mmalerba): Replace with type-only import once TS 3.8 is available +// https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#type-only-imports-exports declare const kagekiri: { querySelectorAll: (selector: string, root: Element) => NodeListOf; }; diff --git a/src/e2e-app/devserver-configure.js b/src/e2e-app/devserver-configure.js index 0a54272655d1..97f65a73e620 100644 --- a/src/e2e-app/devserver-configure.js +++ b/src/e2e-app/devserver-configure.js @@ -3,7 +3,6 @@ require.config({ paths: { 'moment': 'moment/min/moment.min', - 'kagekiri': 'kagekiri/dist/kagekiri.umd.min.js', // Support for lazy-loading of component examples. '@angular/components-examples': 'angular_material/src/components-examples', From 4e211e560100ca584cdab40eaa842f5881305700 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 30 Jan 2020 13:18:25 -0800 Subject: [PATCH 10/14] fix lint and api check --- src/cdk/testing/tests/protractor.e2e.spec.ts | 3 ++- tools/public_api_guard/cdk/testing/protractor.d.ts | 8 ++++++-- tools/public_api_guard/cdk/testing/testbed.d.ts | 12 ++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/cdk/testing/tests/protractor.e2e.spec.ts b/src/cdk/testing/tests/protractor.e2e.spec.ts index 0395a2863c78..8a1601da175e 100644 --- a/src/cdk/testing/tests/protractor.e2e.spec.ts +++ b/src/cdk/testing/tests/protractor.e2e.spec.ts @@ -12,7 +12,8 @@ import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-c // Kagekiri is available globally in the browser. We declare it here so we can use it in the // browser-side script passed to `by.js`. // TODO(mmalerba): Replace with type-only import once TS 3.8 is available -// https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#type-only-imports-exports +// tslint:disable-next-line:max-line-length +// See: https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#type-only-imports-exports declare const kagekiri: { querySelectorAll: (selector: string, root: Element) => NodeListOf; }; diff --git a/tools/public_api_guard/cdk/testing/protractor.d.ts b/tools/public_api_guard/cdk/testing/protractor.d.ts index cfd4cb022104..0761944d3d74 100644 --- a/tools/public_api_guard/cdk/testing/protractor.d.ts +++ b/tools/public_api_guard/cdk/testing/protractor.d.ts @@ -19,12 +19,16 @@ export declare class ProtractorElement implements TestElement { } export declare class ProtractorHarnessEnvironment extends HarnessEnvironment { - protected constructor(rawRootElement: ElementFinder, _queryFn?: (selector: string, root: ElementFinder) => ElementArrayFinder); + protected constructor(rawRootElement: ElementFinder, options?: ProtractorHarnessEnvironmentOptions); protected createEnvironment(element: ElementFinder): HarnessEnvironment; protected createTestElement(element: ElementFinder): TestElement; forceStabilize(): Promise; protected getAllRawElements(selector: string): Promise; protected getDocumentRoot(): ElementFinder; waitForTasksOutsideAngular(): Promise; - static loader(queryFn?: (selector: string, root: ElementFinder) => ElementArrayFinder): HarnessLoader; + static loader(options?: ProtractorHarnessEnvironmentOptions): HarnessLoader; +} + +export interface ProtractorHarnessEnvironmentOptions { + queryFn: (selector: string, root: ElementFinder) => ElementArrayFinder; } diff --git a/tools/public_api_guard/cdk/testing/testbed.d.ts b/tools/public_api_guard/cdk/testing/testbed.d.ts index 41f5eca3abb5..1dd41c96479c 100644 --- a/tools/public_api_guard/cdk/testing/testbed.d.ts +++ b/tools/public_api_guard/cdk/testing/testbed.d.ts @@ -1,14 +1,18 @@ export declare class TestbedHarnessEnvironment extends HarnessEnvironment { - protected constructor(rawRootElement: Element, _fixture: ComponentFixture, _queryFn?: (selector: string, root: Element) => ArrayLike); + protected constructor(rawRootElement: Element, _fixture: ComponentFixture, options?: TestbedHarnessEnvironmentOptions); protected createEnvironment(element: Element): HarnessEnvironment; protected createTestElement(element: Element): TestElement; forceStabilize(): Promise; protected getAllRawElements(selector: string): Promise; protected getDocumentRoot(): Element; waitForTasksOutsideAngular(): Promise; - static documentRootLoader(fixture: ComponentFixture, queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader; - static harnessForFixture(fixture: ComponentFixture, harnessType: ComponentHarnessConstructor, queryFn?: (selector: string, root: Element) => ArrayLike): Promise; - static loader(fixture: ComponentFixture, queryFn?: (selector: string, root: Element) => ArrayLike): HarnessLoader; + static documentRootLoader(fixture: ComponentFixture, options?: TestbedHarnessEnvironmentOptions): HarnessLoader; + static harnessForFixture(fixture: ComponentFixture, harnessType: ComponentHarnessConstructor, options?: TestbedHarnessEnvironmentOptions): Promise; + static loader(fixture: ComponentFixture, options?: TestbedHarnessEnvironmentOptions): HarnessLoader; +} + +export interface TestbedHarnessEnvironmentOptions { + queryFn: (selector: string, root: Element) => ArrayLike; } export declare class UnitTestElement implements TestElement { From 9514f29b7d17a34e1c1cce44fe788ce6d51007e9 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 30 Jan 2020 13:54:26 -0800 Subject: [PATCH 11/14] change lint to allow long urls --- src/cdk/testing/tests/protractor.e2e.spec.ts | 5 ++--- tslint.json | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cdk/testing/tests/protractor.e2e.spec.ts b/src/cdk/testing/tests/protractor.e2e.spec.ts index 8a1601da175e..bb8da1d692cd 100644 --- a/src/cdk/testing/tests/protractor.e2e.spec.ts +++ b/src/cdk/testing/tests/protractor.e2e.spec.ts @@ -11,9 +11,8 @@ import {SubComponentHarness, SubComponentSpecialHarness} from './harnesses/sub-c // Kagekiri is available globally in the browser. We declare it here so we can use it in the // browser-side script passed to `by.js`. -// TODO(mmalerba): Replace with type-only import once TS 3.8 is available -// tslint:disable-next-line:max-line-length -// See: https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#type-only-imports-exports +// TODO(mmalerba): Replace with type-only import once TS 3.8 is available, see: +// https://devblogs.microsoft.com/typescript/announcing-typescript-3-8-beta/#type-only-imports-exports declare const kagekiri: { querySelectorAll: (selector: string, root: Element) => NodeListOf; }; diff --git a/tslint.json b/tslint.json index e085c84e39d7..dc603b940244 100644 --- a/tslint.json +++ b/tslint.json @@ -8,7 +8,8 @@ "max-line-length": [true, { "limit": 100, "check-strings": true, - "check-regex": true + "check-regex": true, + "ignore-pattern": "//\\s+https?://" } ], // Disable this flag because of SHA tslint#48b0c597f9257712c7d1f04b55ed0aa60e333f6a From 7cf853a988e9378ab4d00a9216d7d0b758cbfe38 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Fri, 31 Jan 2020 11:11:02 -0800 Subject: [PATCH 12/14] exclude kagekiri declarations from release --- src/cdk/testing/tests/BUILD.bazel | 11 +++++++++-- .../{kagekiri.d.ts => tests/kagekiri.spec.d.ts} | 0 2 files changed, 9 insertions(+), 2 deletions(-) rename src/cdk/testing/{kagekiri.d.ts => tests/kagekiri.spec.d.ts} (100%) diff --git a/src/cdk/testing/tests/BUILD.bazel b/src/cdk/testing/tests/BUILD.bazel index a0cf73ecff4b..f845b0981c5c 100644 --- a/src/cdk/testing/tests/BUILD.bazel +++ b/src/cdk/testing/tests/BUILD.bazel @@ -9,6 +9,7 @@ ng_module( ["**/*.ts"], exclude = [ "**/*.spec.ts", + "**/*.spec.d.ts", "harnesses/**", ], ), @@ -31,7 +32,10 @@ ts_library( ng_test_library( name = "unit_test_sources", srcs = glob( - ["**/*.spec.ts"], + [ + "**/*.spec.ts", + "**/*.spec.d.ts", + ], exclude = ["**/*.e2e.spec.ts"], ), deps = [ @@ -48,7 +52,10 @@ ng_test_library( ng_e2e_test_library( name = "e2e_test_sources", - srcs = glob(["**/*.e2e.spec.ts"]), + srcs = glob([ + "**/*.e2e.spec.ts", + "**/*.spec.d.ts", + ]), deps = [ ":test_harnesses", "//src/cdk/testing", diff --git a/src/cdk/testing/kagekiri.d.ts b/src/cdk/testing/tests/kagekiri.spec.d.ts similarity index 100% rename from src/cdk/testing/kagekiri.d.ts rename to src/cdk/testing/tests/kagekiri.spec.d.ts From 7d2a814c71245aed063e695c855199d2e57ec5a0 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 5 Mar 2020 12:49:10 -0800 Subject: [PATCH 13/14] expand type of queryFn --- src/cdk/testing/testbed/testbed-harness-environment.ts | 2 +- tools/public_api_guard/cdk/testing/testbed.d.ts | 2 +- yarn.lock | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cdk/testing/testbed/testbed-harness-environment.ts b/src/cdk/testing/testbed/testbed-harness-environment.ts index 43ef85ccac51..52d423601c69 100644 --- a/src/cdk/testing/testbed/testbed-harness-environment.ts +++ b/src/cdk/testing/testbed/testbed-harness-environment.ts @@ -22,7 +22,7 @@ import {UnitTestElement} from './unit-test-element'; /** Options to configure the environment. */ export interface TestbedHarnessEnvironmentOptions { /** The query function used to find DOM elements. */ - queryFn: (selector: string, root: Element) => ArrayLike; + queryFn: (selector: string, root: Element) => Iterable | ArrayLike; } /** The default environment options. */ diff --git a/tools/public_api_guard/cdk/testing/testbed.d.ts b/tools/public_api_guard/cdk/testing/testbed.d.ts index 1dd41c96479c..a44594f0b0ef 100644 --- a/tools/public_api_guard/cdk/testing/testbed.d.ts +++ b/tools/public_api_guard/cdk/testing/testbed.d.ts @@ -12,7 +12,7 @@ export declare class TestbedHarnessEnvironment extends HarnessEnvironment ArrayLike; + queryFn: (selector: string, root: Element) => Iterable | ArrayLike; } export declare class UnitTestElement implements TestElement { diff --git a/yarn.lock b/yarn.lock index 57e752a9985b..b644a9a29aba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3500,6 +3500,11 @@ cssesc@^0.1.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q= +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + csv-streamify@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/csv-streamify/-/csv-streamify-3.0.4.tgz#4cb614c57e3f299cca17b63fdcb4ad167777f47a" From 1dba1d57a788bac96d70d483c09e3cde1a3ba026 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Thu, 5 Mar 2020 14:27:58 -0800 Subject: [PATCH 14/14] remove use of `+` selector --- src/cdk/testing/tests/harnesses/main-component-harness.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdk/testing/tests/harnesses/main-component-harness.ts b/src/cdk/testing/tests/harnesses/main-component-harness.ts index 0c0f9e0f35b7..4694f8297b66 100644 --- a/src/cdk/testing/tests/harnesses/main-component-harness.ts +++ b/src/cdk/testing/tests/harnesses/main-component-harness.ts @@ -83,7 +83,7 @@ export class MainComponentHarness extends ComponentHarness { this.locatorFor('.not-found', SubComponentHarness.with({title: /not found/})); readonly shadows = this.locatorForAll('.in-the-shadows'); readonly deepShadow = this.locatorFor( - '.in-the-shadows + test-sub-shadow-boundary > .in-the-shadows'); + 'test-shadow-boundary test-sub-shadow-boundary > .in-the-shadows'); private _testTools = this.locatorFor(SubComponentHarness);