From 77ed86b9d11ceb33c509288653bbac4e57021b10 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Mon, 14 May 2018 16:58:18 -0700 Subject: [PATCH 1/4] set up virtual scroll page in e2e app --- e2e/components/virtual-scroll-e2e.spec.ts | 22 ++++++++ .../scrolling/virtual-scroll-viewport.scss | 4 +- src/e2e-app/e2e-app-module.ts | 50 ++++++++++--------- src/e2e-app/e2e-app/e2e-app.html | 1 + src/e2e-app/e2e-app/routes.ts | 2 + src/e2e-app/tsconfig-build.json | 4 ++ .../virtual-scroll/virtual-scroll-e2e.html | 21 ++++++++ .../virtual-scroll/virtual-scroll-e2e.ts | 15 ++++++ tools/package-tools/rollup-globals.ts | 13 +++++ 9 files changed, 107 insertions(+), 25 deletions(-) create mode 100644 e2e/components/virtual-scroll-e2e.spec.ts create mode 100644 src/e2e-app/virtual-scroll/virtual-scroll-e2e.html create mode 100644 src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts diff --git a/e2e/components/virtual-scroll-e2e.spec.ts b/e2e/components/virtual-scroll-e2e.spec.ts new file mode 100644 index 000000000000..90c765c4ba5b --- /dev/null +++ b/e2e/components/virtual-scroll-e2e.spec.ts @@ -0,0 +1,22 @@ +import {browser, by, element, ElementFinder} from 'protractor'; + + +fdescribe('cdk-virtual-scroll autosize', () => { + let viewport: ElementFinder; + + beforeEach(() => { + browser.get('/virtual-scroll'); + viewport = element(by.css('.demo-virtual-scroll-uniform-size cdk-virtual-scroll-viewport')); + }); + + describe('with uniform items', () => { + it('should scroll down slowly', async () => { + await browser.executeScript(scrollViewportTo, viewport, 100); + }) + }); +}); + + +function scrollViewportTo(viewportEl: any, offset: number) { + viewportEl.scrollTop = offset; +} diff --git a/src/cdk-experimental/scrolling/virtual-scroll-viewport.scss b/src/cdk-experimental/scrolling/virtual-scroll-viewport.scss index 60f6c3b03edf..b68799167b1e 100644 --- a/src/cdk-experimental/scrolling/virtual-scroll-viewport.scss +++ b/src/cdk-experimental/scrolling/virtual-scroll-viewport.scss @@ -14,11 +14,11 @@ cdk-virtual-scroll-viewport { will-change: contents, transform; } -.cdk-virtual-scroll-orientation-horizontal { +.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper { bottom: 0; } -.cdk-virtual-scroll-orientation-vertical { +.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper { right: 0; } diff --git a/src/e2e-app/e2e-app-module.ts b/src/e2e-app/e2e-app-module.ts index ecb85b2763da..3f2aa9776358 100644 --- a/src/e2e-app/e2e-app-module.ts +++ b/src/e2e-app/e2e-app-module.ts @@ -1,24 +1,7 @@ +import {ScrollingModule} from '@angular/cdk-experimental'; +import {FullscreenOverlayContainer, OverlayContainer} from '@angular/cdk/overlay'; import {NgModule} from '@angular/core'; -import {BrowserModule} from '@angular/platform-browser'; -import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {RouterModule} from '@angular/router'; -import {SimpleCheckboxes} from './checkbox/checkbox-e2e'; -import {E2EApp, Home} from './e2e-app/e2e-app'; -import {IconE2E} from './icon/icon-e2e'; -import {ButtonE2E} from './button/button-e2e'; -import {MenuE2E} from './menu/menu-e2e'; -import {SimpleRadioButtons} from './radio/radio-e2e'; -import {BasicTabs} from './tabs/tabs-e2e'; -import {DialogE2E, TestDialog} from './dialog/dialog-e2e'; -import {GridListE2E} from './grid-list/grid-list-e2e'; -import {ProgressBarE2E} from './progress-bar/progress-bar-e2e'; -import {ProgressSpinnerE2E} from './progress-spinner/progress-spinner-e2e'; -import {FullscreenE2E, TestDialogFullScreen} from './fullscreen/fullscreen-e2e'; -import {E2E_APP_ROUTES} from './e2e-app/routes'; -import {SlideToggleE2E} from './slide-toggle/slide-toggle-e2e'; -import {InputE2E} from './input/input-e2e'; -import {SidenavE2E} from './sidenav/sidenav-e2e'; -import {BlockScrollStrategyE2E} from './block-scroll-strategy/block-scroll-strategy-e2e'; +import {ReactiveFormsModule} from '@angular/forms'; import { MatButtonModule, MatCheckboxModule, @@ -39,9 +22,28 @@ import { MatStepperModule, MatTabsModule, } from '@angular/material'; -import {FullscreenOverlayContainer, OverlayContainer} from '@angular/cdk/overlay'; import {ExampleModule} from '@angular/material-examples'; -import {ReactiveFormsModule} from '@angular/forms'; +import {BrowserModule} from '@angular/platform-browser'; +import {NoopAnimationsModule} from '@angular/platform-browser/animations'; +import {RouterModule} from '@angular/router'; +import {BlockScrollStrategyE2E} from './block-scroll-strategy/block-scroll-strategy-e2e'; +import {ButtonE2E} from './button/button-e2e'; +import {SimpleCheckboxes} from './checkbox/checkbox-e2e'; +import {DialogE2E, TestDialog} from './dialog/dialog-e2e'; +import {E2EApp, Home} from './e2e-app/e2e-app'; +import {E2E_APP_ROUTES} from './e2e-app/routes'; +import {FullscreenE2E, TestDialogFullScreen} from './fullscreen/fullscreen-e2e'; +import {GridListE2E} from './grid-list/grid-list-e2e'; +import {IconE2E} from './icon/icon-e2e'; +import {InputE2E} from './input/input-e2e'; +import {MenuE2E} from './menu/menu-e2e'; +import {ProgressBarE2E} from './progress-bar/progress-bar-e2e'; +import {ProgressSpinnerE2E} from './progress-spinner/progress-spinner-e2e'; +import {SimpleRadioButtons} from './radio/radio-e2e'; +import {SidenavE2E} from './sidenav/sidenav-e2e'; +import {SlideToggleE2E} from './slide-toggle/slide-toggle-e2e'; +import {BasicTabs} from './tabs/tabs-e2e'; +import {VirtualScrollE2E} from './virtual-scroll/virtual-scroll-e2e'; /** * NgModule that contains all Material modules that are required to serve the e2e-app. @@ -66,6 +68,7 @@ import {ReactiveFormsModule} from '@angular/forms'; MatStepperModule, MatTabsModule, MatNativeDateModule, + ScrollingModule, ] }) export class E2eMaterialModule {} @@ -98,7 +101,8 @@ export class E2eMaterialModule {} SlideToggleE2E, TestDialog, TestDialogFullScreen, - BlockScrollStrategyE2E + BlockScrollStrategyE2E, + VirtualScrollE2E, ], bootstrap: [E2EApp], providers: [ diff --git a/src/e2e-app/e2e-app/e2e-app.html b/src/e2e-app/e2e-app/e2e-app.html index b1e16277e1eb..a28e711eaf86 100644 --- a/src/e2e-app/e2e-app/e2e-app.html +++ b/src/e2e-app/e2e-app/e2e-app.html @@ -22,6 +22,7 @@ Tabs Cards Toolbar + Virtual Scroll
diff --git a/src/e2e-app/e2e-app/routes.ts b/src/e2e-app/e2e-app/routes.ts index db20eb234048..58a2e48e7b7b 100644 --- a/src/e2e-app/e2e-app/routes.ts +++ b/src/e2e-app/e2e-app/routes.ts @@ -1,4 +1,5 @@ import {Routes} from '@angular/router'; +import {VirtualScrollE2E} from '../virtual-scroll/virtual-scroll-e2e'; import {Home} from './e2e-app'; import {ButtonE2E} from '../button/button-e2e'; import {BasicTabs} from '../tabs/tabs-e2e'; @@ -47,4 +48,5 @@ export const E2E_APP_ROUTES: Routes = [ {path: 'tabs', component: BasicTabs}, {path: 'cards', component: CardFancyExample}, {path: 'toolbar', component: ToolbarMultirowExample}, + {path: 'virtual-scroll', component: VirtualScrollE2E}, ]; diff --git a/src/e2e-app/tsconfig-build.json b/src/e2e-app/tsconfig-build.json index e369b61a4a58..af370e60fdef 100644 --- a/src/e2e-app/tsconfig-build.json +++ b/src/e2e-app/tsconfig-build.json @@ -26,6 +26,10 @@ "@angular/cdk/*": ["./cdk/*"], "@angular/material": ["./material"], "@angular/material/*": ["./material/*"], + "@angular/material-experimental/*": ["./material-experimental/*"], + "@angular/material-experimental": ["./material-experimental/"], + "@angular/cdk-experimental/*": ["./cdk-experimental/*"], + "@angular/cdk-experimental": ["./cdk-experimental/"], "@angular/material-moment-adapter": ["./material-moment-adapter"], "@angular/material-examples": ["./material-examples"] } diff --git a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html new file mode 100644 index 000000000000..e648fecd3a23 --- /dev/null +++ b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html @@ -0,0 +1,21 @@ +
+

Uniform size

+ +
+ Uniform Item #{{i}} - ({{size}}px) +
+
+
+ +
+

Random size

+ +
+ Variable Item #{{i}} - ({{size}}px) +
+
+
diff --git a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts new file mode 100644 index 000000000000..9675e8183e6c --- /dev/null +++ b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts @@ -0,0 +1,15 @@ +import {Component} from '@angular/core'; + + +const itemSizeSample = [100, 25, 200, 50, 50, 100, 250, 75, 100, 50]; + + +@Component({ + moduleId: module.id, + selector: 'virtual-scroll-e2e', + templateUrl: 'virtual-scroll-e2e.html', +}) +export class VirtualScrollE2E { + uniformItems = Array(1000).fill(50); + variableItems = Array(100).fill(0).reduce(acc => acc.concat(itemSizeSample), []); +} diff --git a/tools/package-tools/rollup-globals.ts b/tools/package-tools/rollup-globals.ts index 19ae925047c8..20b9aa9b93fe 100644 --- a/tools/package-tools/rollup-globals.ts +++ b/tools/package-tools/rollup-globals.ts @@ -12,6 +12,10 @@ const cdkSecondaryEntryPoints = getSubdirectoryNames(join(buildConfig.packagesDi /** List of potential secondary entry-points for the material package. */ const matSecondaryEntryPoints = getSubdirectoryNames(join(buildConfig.packagesDir, 'lib')); +/** List of potential secondary entry-points for the cdk-experimental package. */ +const cdkExperimentalSecondaryEntryPoints = + getSubdirectoryNames(join(buildConfig.packagesDir, 'cdk-experimental')); + /** Object with all cdk entry points in the format of Rollup globals. */ const rollupCdkEntryPoints = cdkSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => { globals[`@angular/cdk/${entryPoint}`] = `ng.cdk.${dashCaseToCamelCase(entryPoint)}`; @@ -24,6 +28,14 @@ const rollupMatEntryPoints = matSecondaryEntryPoints.reduce((globals: any, entry return globals; }, {}); +/** Object with all cdk-experimental entry points in the format of Rollup globals. */ +const rollupCdkExperimentalEntryPoints = + cdkSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => { + globals[`@angular/cdk-experimental/${entryPoint}`] = + `ng.cdkExperimental.${dashCaseToCamelCase(entryPoint)}`; + return globals; + }, {}); + /** Map of globals that are used inside of the different packages. */ export const rollupGlobals = { 'moment': 'moment', @@ -55,6 +67,7 @@ export const rollupGlobals = { // Include secondary entry-points of the cdk and material packages ...rollupCdkEntryPoints, ...rollupMatEntryPoints, + ...rollupCdkExperimentalEntryPoints, 'rxjs': 'Rx', 'rxjs/operators': 'Rx.operators', From 8451e37b28c2071116d06e7324dc3873a14f3ffe Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Mon, 14 May 2018 22:52:48 -0700 Subject: [PATCH 2/4] add gulp task for e2e:watch --- e2e/components/virtual-scroll-e2e.spec.ts | 26 +++++++++++++++++++---- tools/gulp/tasks/e2e.ts | 24 ++++++++++++++++++++- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/e2e/components/virtual-scroll-e2e.spec.ts b/e2e/components/virtual-scroll-e2e.spec.ts index 90c765c4ba5b..c619a35342c8 100644 --- a/e2e/components/virtual-scroll-e2e.spec.ts +++ b/e2e/components/virtual-scroll-e2e.spec.ts @@ -1,7 +1,9 @@ import {browser, by, element, ElementFinder} from 'protractor'; +declare var window: any; -fdescribe('cdk-virtual-scroll autosize', () => { + +fdescribe('autosize cdk-virtual-scroll', () => { let viewport: ElementFinder; beforeEach(() => { @@ -11,12 +13,28 @@ fdescribe('cdk-virtual-scroll autosize', () => { describe('with uniform items', () => { it('should scroll down slowly', async () => { - await browser.executeScript(scrollViewportTo, viewport, 100); - }) + await browser.executeAsyncScript(smoothScrollViewportTo, viewport, 100); + }); }); }); -function scrollViewportTo(viewportEl: any, offset: number) { +function scrollViewportTo(viewportEl: any, offset: number, done: () => void) { viewportEl.scrollTop = offset; + window.requestAnimationFrame(() => done()); +} + + +function smoothScrollViewportTo(viewportEl: any, offset: number, done: () => void) { + let promise = Promise.resolve(); + let curOffset = viewportEl.offsetTop; + const delta = offset - curOffset; + do { + curOffset += Math.min(25, Math.max(-25, delta)); + promise = promise.then(() => new Promise(resolve => { + viewportEl.scrollTop = offset; + window.requestAnimationFrame(() => resolve()); + })); + } while (curOffset != offset); + promise.then(() => done()); } diff --git a/tools/gulp/tasks/e2e.ts b/tools/gulp/tasks/e2e.ts index e49b2ed29ba6..d42943dd75e6 100644 --- a/tools/gulp/tasks/e2e.ts +++ b/tools/gulp/tasks/e2e.ts @@ -2,7 +2,7 @@ import {task} from 'gulp'; import {join} from 'path'; import {ngcBuildTask, copyTask, execNodeTask, serverTask} from '../util/task_helpers'; import {copySync} from 'fs-extra'; -import {buildConfig, sequenceTask, watchFiles} from 'material2-build-tools'; +import {buildConfig, sequenceTask, triggerLivereload, watchFiles} from 'material2-build-tools'; // There are no type definitions available for these imports. const gulpConnect = require('gulp-connect'); @@ -13,6 +13,7 @@ const {outputDir, packagesDir, projectDir} = buildConfig; const releasesDir = join(outputDir, 'releases'); const appDir = join(packagesDir, 'e2e-app'); +const e2eTestDir = join(projectDir, 'e2e'); const outDir = join(outputDir, 'packages', 'e2e-app'); const PROTRACTOR_CONFIG_PATH = join(projectDir, 'test/protractor.conf.js'); @@ -31,6 +32,27 @@ task('e2e', sequenceTask( 'screenshots', )); +task('e2e:watch', sequenceTask( + [':test:protractor:setup', 'serve:e2eapp'], + [':test:protractor', 'material:watch', ':e2e:watch'], +)); + +task(':e2e:watch', () => { + watchFiles([join(appDir, '**/*.+(html|ts|css)'), join(e2eTestDir, '**/*.+(html|ts)')], + [':e2e:rerun'], false); +}); + +task(':e2e:rerun', sequenceTask( + 'e2e-app:copy-assets', + 'e2e-app:build-ts', + ':e2e:reload', + ':test:protractor' +)); + +task(':e2e:reload', () => { + return triggerLivereload(); +}); + /** Task that builds the e2e-app in AOT mode. */ task('e2e-app:build', sequenceTask( 'clean', From 08204232053c4da21e38f4deb88f7c4a40e76672 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Tue, 15 May 2018 10:27:05 -0700 Subject: [PATCH 3/4] add e2e tests for autosize --- .github/CODEOWNERS | 2 + e2e/components/virtual-scroll-e2e.spec.ts | 97 +++++++++++++++++-- .../virtual-scroll/virtual-scroll-e2e.html | 10 +- .../virtual-scroll/virtual-scroll-e2e.ts | 2 +- tools/package-tools/rollup-globals.ts | 2 +- 5 files changed, 97 insertions(+), 16 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 884a325f546e..7464d57455a9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -167,6 +167,7 @@ /e2e/components/stepper-e2e.spec.ts @mmalerba /e2e/components/tabs-e2e.spec.ts @andrewseguin /e2e/components/toolbar-e2e.spec.ts @devversion +/e2e/components/virtual-scroll-e2e.spec.ts @mmalerba /e2e/util/** @jelbourn /src/e2e-app/* @jelbourn /src/e2e-app/block-scroll-strategy/** @andrewseguin @crisbeto @@ -185,6 +186,7 @@ /src/e2e-app/sidenav/** @mmalerba /src/e2e-app/slide-toggle/** @devversion /src/e2e-app/tabs/** @andrewseguin +/src/e2e-app/virtual-scroll/** @mmalerba # Universal app /src/universal-app/** @jelbourn diff --git a/e2e/components/virtual-scroll-e2e.spec.ts b/e2e/components/virtual-scroll-e2e.spec.ts index c619a35342c8..57084e95000e 100644 --- a/e2e/components/virtual-scroll-e2e.spec.ts +++ b/e2e/components/virtual-scroll-e2e.spec.ts @@ -1,38 +1,115 @@ import {browser, by, element, ElementFinder} from 'protractor'; +import {ILocation, ISize} from 'selenium-webdriver'; declare var window: any; -fdescribe('autosize cdk-virtual-scroll', () => { +describe('autosize cdk-virtual-scroll', () => { let viewport: ElementFinder; - beforeEach(() => { - browser.get('/virtual-scroll'); - viewport = element(by.css('.demo-virtual-scroll-uniform-size cdk-virtual-scroll-viewport')); + describe('with uniform items', () => { + beforeEach(() => { + browser.get('/virtual-scroll'); + viewport = element(by.css('.demo-virtual-scroll-uniform-size cdk-virtual-scroll-viewport')); + }); + + it('should scroll down slowly', async () => { + await browser.executeAsyncScript(smoothScrollViewportTo, viewport, 2000); + const offScreen = element(by.css('.demo-virtual-scroll-uniform-size [data-index="39"]')); + const onScreen = element(by.css('.demo-virtual-scroll-uniform-size [data-index="40"]')); + expect(await isVisibleInViewport(offScreen, viewport)).toBe(false); + expect(await isVisibleInViewport(onScreen, viewport)).toBe(true); + }); + + it('should jump scroll position down and slowly scroll back up', async () => { + // The estimate of the total content size is exactly correct, so we wind up scrolled to the + // same place as if we slowly scrolled down. + await browser.executeAsyncScript(scrollViewportTo, viewport, 2000); + const offScreen = element(by.css('.demo-virtual-scroll-uniform-size [data-index="39"]')); + const onScreen = element(by.css('.demo-virtual-scroll-uniform-size [data-index="40"]')); + expect(await isVisibleInViewport(offScreen, viewport)).toBe(false); + expect(await isVisibleInViewport(onScreen, viewport)).toBe(true); + + // As we slowly scroll back up we should wind up back at the start of the content. + await browser.executeAsyncScript(smoothScrollViewportTo, viewport, 0); + const first = element(by.css('.demo-virtual-scroll-uniform-size [data-index="0"]')); + expect(await isVisibleInViewport(first, viewport)).toBe(true); + }); }); - describe('with uniform items', () => { + describe('with variable size', () => { + beforeEach(() => { + browser.get('/virtual-scroll'); + viewport = element(by.css('.demo-virtual-scroll-variable-size cdk-virtual-scroll-viewport')); + }); + it('should scroll down slowly', async () => { - await browser.executeAsyncScript(smoothScrollViewportTo, viewport, 100); + await browser.executeAsyncScript(smoothScrollViewportTo, viewport, 2000); + const offScreen = element(by.css('.demo-virtual-scroll-variable-size [data-index="19"]')); + const onScreen = element(by.css('.demo-virtual-scroll-variable-size [data-index="20"]')); + expect(await isVisibleInViewport(offScreen, viewport)).toBe(false); + expect(await isVisibleInViewport(onScreen, viewport)).toBe(true); + }); + + it('should jump scroll position down and slowly scroll back up', async () => { + // The estimate of the total content size is slightly different than the actual, so we don't + // wind up in the same spot as if we scrolled slowly down. + await browser.executeAsyncScript(scrollViewportTo, viewport, 2000); + const offScreen = element(by.css('.demo-virtual-scroll-variable-size [data-index="18"]')); + const onScreen = element(by.css('.demo-virtual-scroll-variable-size [data-index="19"]')); + expect(await isVisibleInViewport(offScreen, viewport)).toBe(false); + expect(await isVisibleInViewport(onScreen, viewport)).toBe(true); + + // As we slowly scroll back up we should wind up back at the start of the content. As we + // scroll the error from when we jumped the scroll position should be slowly corrected. + await browser.executeAsyncScript(smoothScrollViewportTo, viewport, 0); + const first = element(by.css('.demo-virtual-scroll-variable-size [data-index="0"]')); + expect(await isVisibleInViewport(first, viewport)).toBe(true); }); }); }); +/** Checks if the given element is visible in the given viewport. */ +async function isVisibleInViewport(el: ElementFinder, viewport: ElementFinder): Promise { + if (!await el.isPresent() || !await el.isDisplayed() || !await viewport.isPresent() || + !await viewport.isDisplayed()) { + return false; + } + const viewportRect = getRect(await viewport.getLocation(), await viewport.getSize()); + const elRect = getRect(await el.getLocation(), await el.getSize()); + return elRect.left < viewportRect.right && elRect.right > viewportRect.left && + elRect.top < viewportRect.bottom && elRect.bottom > viewportRect.top; +} + + +/** Gets the rect for an element given its location ans size. */ +function getRect(location: ILocation, size: ISize): + {top: number, left: number, bottom: number, right: number} { + return { + top: location.y, + left: location.x, + bottom: location.y + size.height, + right: location.x + size.width + }; +} + + +/** Immediately scrolls the viewport to the given offset. */ function scrollViewportTo(viewportEl: any, offset: number, done: () => void) { viewportEl.scrollTop = offset; window.requestAnimationFrame(() => done()); } +/** Smoothly scrolls the viewport to the given offset, 25px at a time. */ function smoothScrollViewportTo(viewportEl: any, offset: number, done: () => void) { let promise = Promise.resolve(); - let curOffset = viewportEl.offsetTop; - const delta = offset - curOffset; + let curOffset = viewportEl.scrollTop; do { - curOffset += Math.min(25, Math.max(-25, delta)); + const co = curOffset += Math.min(25, Math.max(-25, offset - curOffset)); promise = promise.then(() => new Promise(resolve => { - viewportEl.scrollTop = offset; + viewportEl.scrollTop = co; window.requestAnimationFrame(() => resolve()); })); } while (curOffset != offset); diff --git a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html index e648fecd3a23..923f076012d4 100644 --- a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html +++ b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html @@ -1,9 +1,10 @@

Uniform size

+ style="height:300px; width:300px; box-shadow:0 0 0 1px black">
+ [style.height.px]="size" [style.background]="odd ? 'cyan' : 'magenta'" + [attr.data-index]="i"> Uniform Item #{{i}} - ({{size}}px)
@@ -12,9 +13,10 @@

Uniform size

Random size

+ style="height:300px; width:300px; box-shadow:0 0 0 1px black">
+ [style.height.px]="size" [style.background]="odd ? 'cyan' : 'magenta'" + [attr.data-index]="i"> Variable Item #{{i}} - ({{size}}px)
diff --git a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts index 9675e8183e6c..b3bc8e5a7ec4 100644 --- a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts +++ b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts @@ -1,7 +1,7 @@ import {Component} from '@angular/core'; -const itemSizeSample = [100, 25, 200, 50, 50, 100, 250, 75, 100, 50]; +const itemSizeSample = [100, 25, 50, 50, 100, 200, 75, 100, 50, 250]; @Component({ diff --git a/tools/package-tools/rollup-globals.ts b/tools/package-tools/rollup-globals.ts index 20b9aa9b93fe..2f3d79519dcb 100644 --- a/tools/package-tools/rollup-globals.ts +++ b/tools/package-tools/rollup-globals.ts @@ -30,7 +30,7 @@ const rollupMatEntryPoints = matSecondaryEntryPoints.reduce((globals: any, entry /** Object with all cdk-experimental entry points in the format of Rollup globals. */ const rollupCdkExperimentalEntryPoints = - cdkSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => { + cdkExperimentalSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => { globals[`@angular/cdk-experimental/${entryPoint}`] = `ng.cdkExperimental.${dashCaseToCamelCase(entryPoint)}`; return globals; From f2935e0ba0f1523cf6541bce99d2a904190ef847 Mon Sep 17 00:00:00 2001 From: Miles Malerba Date: Tue, 15 May 2018 13:52:21 -0700 Subject: [PATCH 4/4] address comments --- .../virtual-scroll/virtual-scroll-e2e.css | 13 ++++++++++ .../virtual-scroll/virtual-scroll-e2e.html | 12 +++------ .../virtual-scroll/virtual-scroll-e2e.ts | 1 + tools/gulp/tasks/e2e.ts | 11 +++++--- tools/package-tools/rollup-globals.ts | 26 +++++++++---------- 5 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 src/e2e-app/virtual-scroll/virtual-scroll-e2e.css diff --git a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.css b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.css new file mode 100644 index 000000000000..adf74dad8e06 --- /dev/null +++ b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.css @@ -0,0 +1,13 @@ +.demo-viewport { + height: 300px; + width: 300px; + box-shadow: 0 0 0 1px black; +} + +.demo-item { + background: magenta; +} + +.demo-odd { + background: cyan; +} diff --git a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html index 923f076012d4..182542cbe186 100644 --- a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html +++ b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.html @@ -1,10 +1,8 @@

Uniform size

- +
+ [style.height.px]="size" [class.demo-odd]="odd" [attr.data-index]="i"> Uniform Item #{{i}} - ({{size}}px)
@@ -12,11 +10,9 @@

Uniform size

Random size

- +
+ [style.height.px]="size" [class.demo-odd]="odd" [attr.data-index]="i"> Variable Item #{{i}} - ({{size}}px)
diff --git a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts index b3bc8e5a7ec4..991d1caf8a68 100644 --- a/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts +++ b/src/e2e-app/virtual-scroll/virtual-scroll-e2e.ts @@ -8,6 +8,7 @@ const itemSizeSample = [100, 25, 50, 50, 100, 200, 75, 100, 50, 250]; moduleId: module.id, selector: 'virtual-scroll-e2e', templateUrl: 'virtual-scroll-e2e.html', + styleUrls: ['virtual-scroll-e2e.css'], }) export class VirtualScrollE2E { uniformItems = Array(1000).fill(50); diff --git a/tools/gulp/tasks/e2e.ts b/tools/gulp/tasks/e2e.ts index d42943dd75e6..242e10866b13 100644 --- a/tools/gulp/tasks/e2e.ts +++ b/tools/gulp/tasks/e2e.ts @@ -22,9 +22,7 @@ const tsconfigPath = join(outDir, 'tsconfig-build.json'); /** Glob that matches all files that need to be copied to the output folder. */ const assetsGlob = join(appDir, '**/*.+(html|css|json|ts)'); -/** - * Builds and serves the e2e-app and runs protractor once the e2e-app is ready. - */ +/** Builds and serves the e2e-app and runs protractor once the e2e-app is ready. */ task('e2e', sequenceTask( [':test:protractor:setup', 'serve:e2eapp'], ':test:protractor', @@ -32,16 +30,22 @@ task('e2e', sequenceTask( 'screenshots', )); +/** + * Builds and serves the e2e-app and runs protractor when the app is ready. Re-runs protractor when + * the app or tests change. + */ task('e2e:watch', sequenceTask( [':test:protractor:setup', 'serve:e2eapp'], [':test:protractor', 'material:watch', ':e2e:watch'], )); +/** Watches the e2e app and tests for changes and triggers a test rerun on change. */ task(':e2e:watch', () => { watchFiles([join(appDir, '**/*.+(html|ts|css)'), join(e2eTestDir, '**/*.+(html|ts)')], [':e2e:rerun'], false); }); +/** Updates the e2e app and runs the protractor tests. */ task(':e2e:rerun', sequenceTask( 'e2e-app:copy-assets', 'e2e-app:build-ts', @@ -49,6 +53,7 @@ task(':e2e:rerun', sequenceTask( ':test:protractor' )); +/** Triggers a reload of the e2e app. */ task(':e2e:reload', () => { return triggerLivereload(); }); diff --git a/tools/package-tools/rollup-globals.ts b/tools/package-tools/rollup-globals.ts index 2f3d79519dcb..fe36cf5dbd0b 100644 --- a/tools/package-tools/rollup-globals.ts +++ b/tools/package-tools/rollup-globals.ts @@ -6,6 +6,16 @@ import {buildConfig} from './build-config'; export const dashCaseToCamelCase = (str: string) => str.replace(/-([a-z])/g, (g) => g[1].toUpperCase()); +/** Generates rollup entry point mappings for the given package and entry points. */ +function generateRollupEntryPoints(packageName: string, entryPoints: string[]): + {[k: string]: string} { + return entryPoints.reduce((globals: {[k: string]: string}, entryPoint: string) => { + globals[`@angular/${packageName}/${entryPoint}`] = + `ng.${dashCaseToCamelCase(packageName)}.${dashCaseToCamelCase(entryPoint)}`; + return globals; + }, {}); +} + /** List of potential secondary entry-points for the cdk package. */ const cdkSecondaryEntryPoints = getSubdirectoryNames(join(buildConfig.packagesDir, 'cdk')); @@ -17,24 +27,14 @@ const cdkExperimentalSecondaryEntryPoints = getSubdirectoryNames(join(buildConfig.packagesDir, 'cdk-experimental')); /** Object with all cdk entry points in the format of Rollup globals. */ -const rollupCdkEntryPoints = cdkSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => { - globals[`@angular/cdk/${entryPoint}`] = `ng.cdk.${dashCaseToCamelCase(entryPoint)}`; - return globals; -}, {}); +const rollupCdkEntryPoints = generateRollupEntryPoints('cdk', cdkSecondaryEntryPoints); /** Object with all material entry points in the format of Rollup globals. */ -const rollupMatEntryPoints = matSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => { - globals[`@angular/material/${entryPoint}`] = `ng.material.${dashCaseToCamelCase(entryPoint)}`; - return globals; -}, {}); +const rollupMatEntryPoints = generateRollupEntryPoints('material', matSecondaryEntryPoints); /** Object with all cdk-experimental entry points in the format of Rollup globals. */ const rollupCdkExperimentalEntryPoints = - cdkExperimentalSecondaryEntryPoints.reduce((globals: any, entryPoint: string) => { - globals[`@angular/cdk-experimental/${entryPoint}`] = - `ng.cdkExperimental.${dashCaseToCamelCase(entryPoint)}`; - return globals; - }, {}); + generateRollupEntryPoints('cdk-experimental', cdkExperimentalSecondaryEntryPoints); /** Map of globals that are used inside of the different packages. */ export const rollupGlobals = {