Skip to content

Commit

Permalink
build: run e2e tests with bazel (#14656)
Browse files Browse the repository at this point in the history
* Builds the e2e app with Bazel
* Serves the e2e app with Bazel
* Runs the e2e tests with Bazel protractor rules
  • Loading branch information
devversion authored and andrewseguin committed Jan 11, 2019
1 parent 5d86a1f commit 326f8bb
Show file tree
Hide file tree
Showing 42 changed files with 546 additions and 715 deletions.
9 changes: 4 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,17 @@ jobs:

- run: bazel test tools/public_api_guard/...

# ----------------------------------------------------------------
# Job that runs the e2e tests with Protractor and Chrome Headless
# ----------------------------------------------------------------
# -----------------------------------------------------------------
# Job that runs the e2e tests with Protractor and Chromium headless
# -----------------------------------------------------------------
e2e_tests:
<<: *job_defaults
resource_class: xlarge
steps:
- *checkout_code
- *restore_cache
- *yarn_install

- run: yarn gulp ci:e2e
- run: bazel test e2e/...

# ------------------------------------------------------------------------------------------
# Job that runs the unit tests on locally installed browsers (Chrome and Firefox headless).
Expand Down
6 changes: 4 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ http_archive(
# Add TypeScript rules
http_archive(
name = "build_bazel_rules_typescript",
url = "https://github.com/bazelbuild/rules_typescript/archive/0.22.0.zip",
strip_prefix = "rules_typescript-0.22.0",
# Explicitly depend on https://github.com/bazelbuild/rules_typescript/pull/327 which fixes the devserver
# for windows. Once this has been reviewed and merged, we can switch back to a normal release.
url = "https://github.com/bazelbuild/rules_typescript/archive/1bb017e2f9c58f96bac8ddda2ed4a170282bc58e.zip",
strip_prefix = "rules_typescript-1bb017e2f9c58f96bac8ddda2ed4a170282bc58e",
)

# Add Angular source and Bazel rules.
Expand Down
30 changes: 30 additions & 0 deletions e2e/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package(default_visibility=["//visibility:public"])

load("@angular//:index.bzl", "protractor_web_test_suite")
load("//tools:defaults.bzl", "ts_library")

ts_library(
name = "e2e_specs_lib",
srcs = glob(["**/*.ts"]),
tsconfig = ":tsconfig.json",
deps = [
"@matdeps//@types/jasmine",
"@matdeps//protractor"
]
)

protractor_web_test_suite(
name = "e2e",
configuration = ":protractor.conf.js",
on_prepare = ":start-devserver.js",
server = "//src/e2e-app:devserver",
deps = [
"@matdeps//protractor",
":e2e_specs_lib"
],
data = [
"@angular//packages/bazel/src/protractor/utils",
"//tools/axe-protractor",
],
)

66 changes: 34 additions & 32 deletions e2e/components/block-scroll-strategy-e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,44 @@ describe('scroll blocking', () => {
afterEach(() => clickOn('disable'));

it('should not be able to scroll programmatically along the x axis', async () => {
scrollPage(0, 100);
await scrollPage(0, 100);
expect((await getScrollPosition()).y).toBe(100, 'Expected the page to be scrollable.');

clickOn('enable');
scrollPage(0, 200);
await clickOn('enable');
await scrollPage(0, 200);
expect((await getScrollPosition()).y).toBe(100, 'Expected the page not to be scrollable.');

clickOn('disable');
scrollPage(0, 300);
await clickOn('disable');
await scrollPage(0, 300);
expect((await getScrollPosition()).y).toBe(300, 'Exected page to be scrollable again.');
});

it('should not be able to scroll programmatically along the y axis', async () => {
scrollPage(100, 0);
await scrollPage(100, 0);
expect((await getScrollPosition()).x).toBe(100, 'Expected the page to be scrollable.');

clickOn('enable');
scrollPage(200, 0);
await clickOn('enable');
await scrollPage(200, 0);
expect((await getScrollPosition()).x).toBe(100, 'Expected the page not to be scrollable.');

clickOn('disable');
scrollPage(300, 0);
await clickOn('disable');
await scrollPage(300, 0);
expect((await getScrollPosition()).x).toBe(300, 'Exected page to be scrollable again.');
});

it('should not be able to scroll via the keyboard along the y axis', async () => {
const body = element(by.tagName('body'));

scrollPage(0, 100);
await scrollPage(0, 100);
expect((await getScrollPosition()).y).toBe(100, 'Expected the page to be scrollable.');

clickOn('enable');
await clickOn('enable');
await body.sendKeys(Key.ARROW_DOWN);
await body.sendKeys(Key.ARROW_DOWN);
await body.sendKeys(Key.ARROW_DOWN);
expect((await getScrollPosition()).y).toBe(100, 'Expected the page not to be scrollable.');

clickOn('disable');
await clickOn('disable');
await body.sendKeys(Key.ARROW_DOWN);
await body.sendKeys(Key.ARROW_DOWN);
await body.sendKeys(Key.ARROW_DOWN);
Expand All @@ -55,16 +55,16 @@ describe('scroll blocking', () => {
it('should not be able to scroll via the keyboard along the x axis', async () => {
const body = element(by.tagName('body'));

scrollPage(100, 0);
await scrollPage(100, 0);
expect((await getScrollPosition()).x).toBe(100, 'Expected the page to be scrollable.');

clickOn('enable');
await clickOn('enable');
await body.sendKeys(Key.ARROW_RIGHT);
await body.sendKeys(Key.ARROW_RIGHT);
await body.sendKeys(Key.ARROW_RIGHT);
expect((await getScrollPosition()).x).toBe(100, 'Expected the page not to be scrollable.');

clickOn('disable');
await clickOn('disable');
await body.sendKeys(Key.ARROW_RIGHT);
await body.sendKeys(Key.ARROW_RIGHT);
await body.sendKeys(Key.ARROW_RIGHT);
Expand All @@ -76,40 +76,42 @@ describe('scroll blocking', () => {
async () => {
const scroller = element(by.id('scroller'));

browser.executeScript(`document.getElementById('scroller').scrollTop = 200;`);
scrollPage(0, 100);
await browser.executeScript(`document.getElementById('scroller').scrollTop = 200;`);
await scrollPage(0, 100);
expect((await getScrollPosition()).y).toBe(100, 'Expected the page to be scrollable.');

clickOn('enable');
scroller.sendKeys(Key.ARROW_DOWN);
scroller.sendKeys(Key.ARROW_DOWN);
scroller.sendKeys(Key.ARROW_DOWN);
await clickOn('enable');
await scroller.sendKeys(Key.ARROW_DOWN);
await scroller.sendKeys(Key.ARROW_DOWN);
await scroller.sendKeys(Key.ARROW_DOWN);

expect((await getScrollPosition()).y).toBe(100, 'Expected the page not to have scrolled.');
});

it('should not be able to scroll the page after reaching the end of an element along the x axis',
async () => {
const scroller = element(by.id('scroller'));

browser.executeScript(`document.getElementById('scroller').scrollLeft = 200;`);
scrollPage(100, 0);
await browser.executeScript(`document.getElementById('scroller').scrollLeft = 200;`);
await scrollPage(100, 0);
expect((await getScrollPosition()).x).toBe(100, 'Expected the page to be scrollable.');

clickOn('enable');
scroller.sendKeys(Key.ARROW_RIGHT);
scroller.sendKeys(Key.ARROW_RIGHT);
scroller.sendKeys(Key.ARROW_RIGHT);
await clickOn('enable');
await scroller.sendKeys(Key.ARROW_RIGHT);
await scroller.sendKeys(Key.ARROW_RIGHT);
await scroller.sendKeys(Key.ARROW_RIGHT);

expect((await getScrollPosition()).x).toBe(100, 'Expected the page not to have scrolled.');
});
});

// Clicks on a button programmatically. Note that we can't use Protractor's `.click`, because
// it performs a real click, which will scroll the button into view.
function clickOn(id: string) {
browser.executeScript(`document.getElementById('${id}').click()`);
async function clickOn(id: string) {
await browser.executeScript(`document.getElementById('${id}').click()`);
}

// Scrolls the page to the specified coordinates.
function scrollPage(x: number, y: number) {
return browser.executeScript(`window.scrollTo(${x}, ${y});`);
async function scrollPage(x: number, y: number) {
await browser.executeScript(`window.scrollTo(${x}, ${y});`);
}
10 changes: 6 additions & 4 deletions e2e/components/button-e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import {browser, by, element, ExpectedConditions} from 'protractor';

describe('button', () => {

describe('disabling behavior', () => {
beforeEach(() => browser.get('/button'));

beforeEach(async () => await browser.get('/button'));

it('should prevent click handlers from executing when disabled', async () => {
element(by.id('test-button')).click();
await element(by.id('test-button')).click();
expect(await element(by.id('click-counter')).getText()).toEqual('1');

await browser.wait(ExpectedConditions.not(
ExpectedConditions.presenceOf(element(by.css('div.mat-ripple-element')))));

element(by.id('disable-toggle')).click();
element(by.id('test-button')).click();
await element(by.id('disable-toggle')).click();
await element(by.id('test-button')).click();
expect(await element(by.id('click-counter')).getText()).toEqual('1');

await browser.wait(ExpectedConditions.not(
Expand Down
4 changes: 2 additions & 2 deletions e2e/components/button-toggle-e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import {browser, by, element} from 'protractor';

describe('button-toggle', () => {

beforeEach(() => browser.get('/button-toggle'));
beforeEach(async () => await browser.get('/button-toggle'));

it('should show a button-toggle', async () => {
expect(element(by.tagName('mat-button-toggle'))).toBeDefined();
expect(await element(by.tagName('mat-button-toggle'))).toBeDefined();
});

});
5 changes: 2 additions & 3 deletions e2e/components/card-e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import {browser, by, element} from 'protractor';

describe('mat-card', () => {

beforeEach(() => browser.get('/cards'));
beforeEach(async () => await browser.get('/cards'));

it('should show a card', async () => {
const card = element(by.tagName('mat-card'));
expect(card).toBeDefined();
expect(await element(by.tagName('mat-card'))).toBeDefined();
});

});
24 changes: 12 additions & 12 deletions e2e/components/checkbox-e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,31 @@ import {browser, by, element, Key} from 'protractor';
describe('checkbox', () => {

describe('check behavior', () => {
beforeEach(() => browser.get('/checkbox'));
beforeEach(async () => await browser.get('/checkbox'));

it('should be checked when clicked, and unchecked when clicked again', async () => {
let checkboxEl = element(by.id('test-checkbox'));
let inputEl = element(by.css('input[id=test-checkbox-input]'));
const checkboxEl = element(by.id('test-checkbox'));
const inputEl = element(by.css('input[id=test-checkbox-input]'));

checkboxEl.click();
await checkboxEl.click();

expect(inputEl.getAttribute('checked'))
expect(await inputEl.getAttribute('checked'))
.toBeTruthy('Expect checkbox "checked" property to be true');

checkboxEl.click();
await checkboxEl.click();

expect(inputEl.getAttribute('checked'))
expect(await inputEl.getAttribute('checked'))
.toBeFalsy('Expect checkbox "checked" property to be false');
});

it('should toggle the checkbox when pressing space', () => {
let inputEl = element(by.css('input[id=test-checkbox-input]'));
it('should toggle the checkbox when pressing space', async () => {
const inputEl = element(by.css('input[id=test-checkbox-input]'));

expect(inputEl.getAttribute('checked'))
expect(await inputEl.getAttribute('checked'))
.toBeFalsy('Expect checkbox "checked" property to be false');
inputEl.sendKeys(Key.SPACE);
await inputEl.sendKeys(Key.SPACE);

expect(inputEl.getAttribute('checked'))
expect(await inputEl.getAttribute('checked'))
.toBeTruthy('Expect checkbox "checked" property to be true');
});
});
Expand Down
Loading

0 comments on commit 326f8bb

Please sign in to comment.