Skip to content

Commit a935da5

Browse files
authored
feat(test): playwright configuration and e2e tests (#3)
- fix cdk tree component - fix lint issues - add .angular folder to .gitignore - remove templates from source control - add templates to gitignore - add console.log error test - add tab content visibility test - replace waitForTimeout with waitForLoadState - improve playwright configuration - change assertion in a GitHub link test - replace click handlers in Page Objects with direct `click()` method invocations - simplify `shouldRender` method in `cdk-tree` component - add test packackage.json script
1 parent 2c24214 commit a935da5

23 files changed

+42688
-14526
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ speed-measure-plugin.json
2222
*.launch
2323
.settings/
2424
*.sublime-workspace
25+
.angular
2526

2627
# IDE - VSCode
2728
.vscode/*
@@ -46,3 +47,8 @@ testem.log
4647
# System Files
4748
.DS_Store
4849
Thumbs.db
50+
51+
templates
52+
/test-results/
53+
/playwright-report/
54+
/playwright/.cache/
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type { Locator, Page } from '@playwright/test';
2+
3+
export class AngularMaterialButtonsPage {
4+
readonly page: Page;
5+
readonly basicButtons: Locator;
6+
readonly basicLinks: Locator;
7+
readonly disabledBasicButtons: Locator;
8+
readonly raisedButtons: Locator;
9+
readonly raisedLinks: Locator;
10+
readonly disabledRaisedButtons: Locator;
11+
readonly strokedButtons: Locator;
12+
readonly strokedLinks: Locator;
13+
readonly disabledStrokedButtons: Locator;
14+
readonly flatButtons: Locator;
15+
readonly flatLinks: Locator;
16+
readonly disabledFlatButtons: Locator;
17+
readonly iconButtons: Locator;
18+
19+
constructor(page: Page) {
20+
this.page = page;
21+
this.basicButtons = page.getByTestId('basic-buttons').getByRole('button');
22+
this.basicLinks = page.getByTestId('basic-buttons').getByRole('link');
23+
this.disabledBasicButtons = page.getByTestId('basic-buttons').getByText('Disabled');
24+
this.raisedButtons = page.getByTestId('raised-buttons').getByRole('button');
25+
this.raisedLinks = page.getByTestId('raised-buttons').getByRole('link');
26+
this.disabledRaisedButtons = page.getByTestId('raised-buttons').getByText('Disabled');
27+
this.strokedButtons = page.getByTestId('stroked-buttons').getByRole('button');
28+
this.strokedLinks = page.getByTestId('stroked-buttons').getByRole('link');
29+
this.disabledStrokedButtons = page.getByTestId('stroked-buttons').getByText('Disabled');
30+
this.flatButtons = page.getByTestId('flat-buttons').getByRole('button');
31+
this.flatLinks = page.getByTestId('flat-buttons').getByRole('link');
32+
this.disabledFlatButtons = page.getByTestId('flat-buttons').getByText('Disabled');
33+
this.iconButtons = page.getByTestId('icon-buttons').getByRole('button');
34+
}
35+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { Locator, Page } from '@playwright/test';
2+
3+
export class AngularMaterialCdkTreePage {
4+
readonly page: Page;
5+
readonly apple: Locator;
6+
readonly broccoli: Locator;
7+
readonly pumpkins: Locator;
8+
9+
constructor(page: Page) {
10+
this.page = page;
11+
this.apple = page.getByRole('treeitem', { name: 'Apple' });
12+
this.broccoli = page.getByRole('treeitem', { name: 'Broccoli' })
13+
this.pumpkins = page.getByRole('treeitem', { name: 'Pumpkins' });
14+
}
15+
16+
async clickOnFruit(): Promise<void> {
17+
await this.page.getByRole('button', { name: 'toggle Fruit' }).click();
18+
}
19+
20+
async clickOnVegetables(): Promise<void> {
21+
await this.page.getByRole('button', { name: 'toggle Vegetables' }).click();
22+
}
23+
24+
async clickOnGreen(): Promise<void> {
25+
await this.page.getByRole('button', { name: 'toggle Green' }).click();
26+
}
27+
28+
async clickOnOrange(): Promise<void> {
29+
await this.page.getByRole('button', { name: 'toggle Orange' }).click();
30+
}
31+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { Locator, Page } from '@playwright/test';
2+
3+
export class AngularMaterialTabsPage {
4+
readonly page: Page;
5+
readonly cdkTree: Locator;
6+
readonly tabThree: Locator;
7+
readonly tabThreeContent: Locator;
8+
readonly buttons: Locator;
9+
10+
constructor(page: Page) {
11+
this.page = page;
12+
this.cdkTree = page.getByRole('tab', { name: 'CDK Tree' });
13+
this.tabThree = page.getByRole('tab', { name: 'Tab Three' });
14+
this.tabThreeContent = page.getByTestId('ng-tab-three-content');
15+
this.buttons = page.getByRole('tab', { name: 'Buttons' });
16+
}
17+
}

e2e/pages/angular-panel-page.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { Page } from '@playwright/test';
2+
3+
export class AngularPanelPage {
4+
readonly page: Page;
5+
6+
constructor(page: Page) {
7+
this.page = page;
8+
}
9+
10+
async clickOnAngularExpansionPanel(): Promise<void> {
11+
await this.page.getByRole('button', { name: 'Angular Material Components built for Angular' }).click();
12+
}
13+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { Locator, Page } from '@playwright/test';
2+
3+
export class AngularjsMaterialButtonsPage {
4+
readonly page: Page;
5+
readonly buttons: Locator;
6+
readonly flatButtons: Locator;
7+
readonly raisedButtons: Locator;
8+
9+
constructor(page: Page) {
10+
this.page = page;
11+
this.buttons = page.getByRole('tab', { name: 'Buttons' });
12+
this.flatButtons = page.getByTestId('flat-buttons-section').getByRole('button');
13+
this.raisedButtons = page.getByTestId('raised-buttons-section').getByRole('button');
14+
}
15+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { Locator, Page } from '@playwright/test';
2+
3+
export class AngularjsMaterialTabsPage {
4+
readonly page: Page;
5+
readonly tabTwo: Locator;
6+
readonly tabTwoContent: Locator;
7+
readonly tabThree: Locator;
8+
readonly tabThreeContent: Locator;
9+
readonly buttons: Locator;
10+
11+
constructor(page: Page) {
12+
this.page = page;
13+
this.tabTwo = page.getByRole('tab', { name: 'Tab two' });
14+
this.tabTwoContent = page.getByTestId('tab-two-content');
15+
this.tabThree = page.getByRole('tab', { name: 'Tab three' });
16+
this.tabThreeContent = page.getByTestId('ngjs-tab-three-content');
17+
this.buttons = page.getByRole('tab', { name: 'Buttons' });
18+
}
19+
}

e2e/pages/angularjs-panel-page.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { Page } from '@playwright/test';
2+
3+
export class AngularJSPanelPage {
4+
readonly page: Page;
5+
6+
constructor(page: Page) {
7+
this.page = page;
8+
}
9+
10+
async clickOnAngularJSExpansionPanel(): Promise<void> {
11+
await this.page.getByRole('button', { name: 'AngularJS Material Components built for AngularJS 1.x' }).click();
12+
}
13+
}

e2e/pages/top-nav-page.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { Locator, Page } from '@playwright/test';
2+
3+
export class TopNavPage {
4+
readonly page: Page;
5+
title: Locator;
6+
7+
constructor(page: Page) {
8+
this.page = page;
9+
this.title = page.getByText('Angular Upgrade and Angular CLI Demo');
10+
}
11+
12+
async clickOnGitHubIcon(): Promise<void> {
13+
await this.page.getByTestId('github').click();
14+
}
15+
}
16+
17+

e2e/tests/app.e2e.ts

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { expect, test } from '@playwright/test';
2+
import { AngularJSPanelPage } from '../pages/angularjs-panel-page';
3+
import { AngularPanelPage } from '../pages/angular-panel-page';
4+
import { AngularjsMaterialTabsPage } from '../pages/angularjs-material-tabs-page';
5+
import { AngularjsMaterialButtonsPage } from '../pages/angularjs-material-buttons-page';
6+
import { AngularMaterialTabsPage } from '../pages/angular-material-tabs-page';
7+
import { AngularMaterialCdkTreePage } from '../pages/angular-material-cdk-tree-page';
8+
import { AngularMaterialButtonsPage } from '../pages/angular-material-buttons-page';
9+
import { TopNavPage } from '../pages/top-nav-page';
10+
11+
test.describe('AngularJS-Angular hybrid app', () => {
12+
let errorLogs: string[];
13+
14+
test.beforeEach(async ({page}) => {
15+
errorLogs = [];
16+
17+
page.on('console', message => {
18+
if (message.type() === 'error') {
19+
errorLogs.push(message.text());
20+
}
21+
});
22+
23+
page.on('pageerror', err => {
24+
errorLogs.push(err.message);
25+
});
26+
27+
await page.goto('');
28+
});
29+
30+
test.afterEach(async () => {
31+
expect(errorLogs).toStrictEqual([]);
32+
});
33+
34+
test.describe('Components built for AngularJS', () => {
35+
test.beforeEach(async ({page}) => {
36+
const angularJsPanelPage = new AngularJSPanelPage(page);
37+
await angularJsPanelPage.clickOnAngularJSExpansionPanel();
38+
});
39+
40+
test('Tabs', async ({page}) => {
41+
const angularjsMaterialTabsPage = new AngularjsMaterialTabsPage(page);
42+
43+
await angularjsMaterialTabsPage.tabTwo.click();
44+
await expect(angularjsMaterialTabsPage.tabTwo).toHaveText('Tab two');
45+
await expect(angularjsMaterialTabsPage.tabTwoContent).toHaveText('Tab two content');
46+
47+
await angularjsMaterialTabsPage.tabThree.click();
48+
await expect(angularjsMaterialTabsPage.tabThree).toHaveText('Tab three');
49+
await expect(angularjsMaterialTabsPage.tabThreeContent).toHaveText('Tab three content');
50+
await expect(angularjsMaterialTabsPage.tabTwoContent).not.toBeVisible();
51+
52+
await angularjsMaterialTabsPage.buttons.click();
53+
await expect(angularjsMaterialTabsPage.buttons).toHaveText('Buttons');
54+
await expect(angularjsMaterialTabsPage.tabThreeContent).not.toBeVisible();
55+
});
56+
57+
test('Buttons', async ({page}) => {
58+
const angularjsMaterialButtonsPage = new AngularjsMaterialButtonsPage(page);
59+
60+
await page.waitForLoadState('domcontentloaded');
61+
62+
await expect(await angularjsMaterialButtonsPage.flatButtons.all()).toHaveLength(5);
63+
await expect(await angularjsMaterialButtonsPage.raisedButtons.all()).toHaveLength(5);
64+
});
65+
});
66+
67+
test.describe('Components built for Angular', () => {
68+
test.beforeEach(async ({page}) => {
69+
const angularPanelPage = new AngularPanelPage(page);
70+
await angularPanelPage.clickOnAngularExpansionPanel();
71+
});
72+
73+
test('Tabs', async ({page}) => {
74+
const angularMaterialTabsPage = new AngularMaterialTabsPage(page);
75+
76+
await angularMaterialTabsPage.cdkTree.click();
77+
await expect(angularMaterialTabsPage.cdkTree).toHaveText('CDK Tree');
78+
79+
await angularMaterialTabsPage.tabThree.click();
80+
await expect(angularMaterialTabsPage.tabThree).toHaveText('Tab Three');
81+
await expect(angularMaterialTabsPage.tabThreeContent).toHaveText('Tab three content');
82+
83+
await angularMaterialTabsPage.buttons.click();
84+
await expect(angularMaterialTabsPage.buttons).toHaveText('Buttons');
85+
await expect(angularMaterialTabsPage.tabThreeContent).not.toBeVisible();
86+
});
87+
88+
test('Buttons', async ({page}) => {
89+
const angularMaterialButtonsPage = new AngularMaterialButtonsPage(page);
90+
91+
await page.waitForLoadState('domcontentloaded');
92+
93+
await expect(await angularMaterialButtonsPage.basicButtons.all()).toHaveLength(5);
94+
await expect(await angularMaterialButtonsPage.basicLinks.all()).toHaveLength(1);
95+
await expect(angularMaterialButtonsPage.disabledBasicButtons).toBeDisabled();
96+
97+
await expect(await angularMaterialButtonsPage.raisedButtons.all()).toHaveLength(5);
98+
await expect(await angularMaterialButtonsPage.raisedLinks.all()).toHaveLength(1);
99+
await expect(angularMaterialButtonsPage.disabledRaisedButtons).toBeDisabled();
100+
101+
await expect(await angularMaterialButtonsPage.strokedButtons.all()).toHaveLength(5);
102+
await expect(await angularMaterialButtonsPage.strokedLinks.all()).toHaveLength(1);
103+
await expect(angularMaterialButtonsPage.disabledStrokedButtons).toBeDisabled();
104+
105+
await expect(await angularMaterialButtonsPage.flatButtons.all()).toHaveLength(5);
106+
await expect(await angularMaterialButtonsPage.flatLinks.all()).toHaveLength(1);
107+
await expect(angularMaterialButtonsPage.disabledFlatButtons).toBeDisabled();
108+
109+
await expect(await angularMaterialButtonsPage.iconButtons.all()).toHaveLength(5);
110+
});
111+
112+
test('CDK Tree', async ({page}) => {
113+
const angularMaterialTabsPage = new AngularMaterialTabsPage(page);
114+
const angularMaterialCdkTreePage = new AngularMaterialCdkTreePage(page);
115+
116+
await angularMaterialTabsPage.cdkTree.click();
117+
118+
await angularMaterialCdkTreePage.clickOnFruit();
119+
await expect(angularMaterialCdkTreePage.apple).toBeVisible();
120+
121+
await angularMaterialCdkTreePage.clickOnFruit();
122+
await expect(angularMaterialCdkTreePage.apple).not.toBeVisible();
123+
124+
await angularMaterialCdkTreePage.clickOnVegetables();
125+
await angularMaterialCdkTreePage.clickOnGreen();
126+
await expect(angularMaterialCdkTreePage.broccoli).toBeVisible();
127+
128+
await angularMaterialCdkTreePage.clickOnOrange();
129+
await expect(angularMaterialCdkTreePage.pumpkins).toBeVisible();
130+
131+
await angularMaterialCdkTreePage.clickOnVegetables();
132+
await expect(angularMaterialCdkTreePage.broccoli).not.toBeVisible();
133+
await expect(angularMaterialCdkTreePage.pumpkins).not.toBeVisible();
134+
135+
});
136+
});
137+
138+
test.describe('TopNav', () => {
139+
test('Title', async ({page}) => {
140+
const topNavPage = new TopNavPage(page);
141+
const title = await topNavPage.title;
142+
await expect(title).toHaveText('Angular Upgrade and Angular CLI Demo');
143+
});
144+
145+
test('GitHub link', async ({page}) => {
146+
const topNavPage = new TopNavPage(page);
147+
148+
await topNavPage.clickOnGitHubIcon();
149+
150+
const githubPage = await page.waitForEvent('popup');
151+
152+
await expect(githubPage.url()).toBe('https://github.com/Splaktar/angularjs-angular-material-hybrid-demo');
153+
});
154+
});
155+
});

0 commit comments

Comments
 (0)