Skip to content
This repository was archived by the owner on Jun 18, 2023. It is now read-only.

Commit 833ae6f

Browse files
committed
feat: Add basic playwright ui tests
1 parent dc948d4 commit 833ae6f

File tree

12 files changed

+258
-5
lines changed

12 files changed

+258
-5
lines changed

.github/workflows/build-on-pull-request.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66

77
jobs:
88
build:
9+
timeout-minutes: 30
910
runs-on: ubuntu-latest
1011
steps:
1112
- uses: actions/checkout@v2
@@ -18,5 +19,23 @@ jobs:
1819
- name: Setup Gradle
1920
uses: gradle/gradle-build-action@v2
2021

22+
# run build
2123
- name: Build
2224
run: ./gradlew build
25+
26+
# prepare ui test
27+
- name: Install Playwright Browsers
28+
run: npx playwright install --with-deps
29+
30+
- name: Start application in the background
31+
run: ./gradlew npm_run_start &
32+
# run ui tests
33+
- name: E2E
34+
run: ./gradlew npm_run_e2e
35+
36+
- uses: actions/upload-artifact@v3
37+
if: always()
38+
with:
39+
name: playwright-report
40+
path: playwright-report/
41+
retention-days: 30

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,8 @@ testem.log
4747
.DS_Store
4848
Thumbs.db
4949
/gradle.properties
50+
51+
# Playwright
52+
/test-results/
53+
/playwright-report/
54+
/playwright/.cache/

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ It contains multiple mocks - including the ones from the springwolf-core example
2727

2828
To update the mock data, run `npm run update-mocks`.
2929

30+
## E2E tests
31+
32+
E2E tests are written with [playwright](https://playwright.dev).
33+
To run them:
34+
1. start the development server with `npm run start`
35+
2. run the tests with `npm run test`
36+
37+
During development of test you might find the codegen feature useful:
38+
`npx playwright codegen localhost:4200`
39+
3040
## Release
3141

3242
Releasing is done by running the gradle task `publish`. For local development, use `publishToMavenLocal`.

package-lock.json

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
"ng": "ng",
66
"start": "ng serve",
77
"build": "ng build --prod --base-href=./",
8-
"test": "ng test",
98
"lint": "ng lint",
10-
"e2e": "ng e2e",
9+
"e2e": "playwright test",
1110
"update-mocks": "node ./script/update_mock_data.js"
1211
},
1312
"private": true,
@@ -33,6 +32,7 @@
3332
"@angular-devkit/build-angular": "~0.901.6",
3433
"@angular/cli": "~9.1.6",
3534
"@angular/compiler-cli": "~9.1.7",
35+
"@playwright/test": "^1.27.1",
3636
"@types/jasmine": "~3.5.0",
3737
"@types/jasminewd2": "~2.0.3",
3838
"@types/node": "^12.11.1",

playwright.config.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import type { PlaywrightTestConfig } from '@playwright/test';
2+
import { devices } from '@playwright/test';
3+
4+
/**
5+
* Read environment variables from file.
6+
* https://github.com/motdotla/dotenv
7+
*/
8+
// require('dotenv').config();
9+
10+
/**
11+
* See https://playwright.dev/docs/test-configuration.
12+
*/
13+
const config: PlaywrightTestConfig = {
14+
testDir: './tests',
15+
/* Maximum time one test can run for. */
16+
timeout: 30 * 1000,
17+
expect: {
18+
/**
19+
* Maximum time expect() should wait for the condition to be met.
20+
* For example in `await expect(locator).toHaveText();`
21+
*/
22+
timeout: 5000
23+
},
24+
/* Run tests in files in parallel */
25+
fullyParallel: true,
26+
/* Fail the build on CI if you accidentally left test.only in the source code. */
27+
forbidOnly: !!process.env.CI,
28+
/* Retry on CI only */
29+
retries: process.env.CI ? 2 : 0,
30+
/* Opt out of parallel tests on CI. */
31+
workers: process.env.CI ? 1 : undefined,
32+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
33+
reporter: 'html',
34+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
35+
use: {
36+
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
37+
actionTimeout: 0,
38+
/* Base URL to use in actions like `await page.goto('/')`. */
39+
// baseURL: 'http://localhost:3000',
40+
41+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
42+
trace: 'on-first-retry',
43+
},
44+
45+
/* Configure projects for major browsers */
46+
projects: [
47+
{
48+
name: 'chromium',
49+
use: {
50+
...devices['Desktop Chrome'],
51+
},
52+
},
53+
54+
{
55+
name: 'firefox',
56+
use: {
57+
...devices['Desktop Firefox'],
58+
},
59+
},
60+
61+
// {
62+
// name: 'webkit',
63+
// use: {
64+
// ...devices['Desktop Safari'],
65+
// },
66+
// },
67+
68+
/* Test against mobile viewports. */
69+
// {
70+
// name: 'Mobile Chrome',
71+
// use: {
72+
// ...devices['Pixel 5'],
73+
// },
74+
// },
75+
// {
76+
// name: 'Mobile Safari',
77+
// use: {
78+
// ...devices['iPhone 12'],
79+
// },
80+
// },
81+
82+
/* Test against branded browsers. */
83+
// {
84+
// name: 'Microsoft Edge',
85+
// use: {
86+
// channel: 'msedge',
87+
// },
88+
// },
89+
// {
90+
// name: 'Google Chrome',
91+
// use: {
92+
// channel: 'chrome',
93+
// },
94+
// },
95+
],
96+
97+
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
98+
// outputDir: 'test-results/',
99+
100+
/* Run your local dev server before starting the tests */
101+
// webServer: {
102+
// command: 'npm run start',
103+
// port: 3000,
104+
// },
105+
};
106+
107+
export default config;

src/app/channels/channels.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ <h1>Channels</h1>
1919
</ul>
2020

2121
<mat-accordion>
22-
<mat-expansion-panel *ngFor="let channel of channels" [id]="channel.anchorIdentifier" [expanded]="selectedChannel == channel.anchorIdentifier" (opened)="this.setChannelSelection(channel)">
22+
<mat-expansion-panel *ngFor="let channel of channels" [id]="channel.anchorIdentifier.substr(1)" [expanded]="selectedChannel == channel.anchorIdentifier" (opened)="this.setChannelSelection(channel)">
2323
<mat-expansion-panel-header>
2424
<mat-panel-title fxLayout fxLayoutAlign="flex-start center" fxLayoutGap="16px">
2525
<div class="badge protocol-badge" >

src/app/schemas/schemas.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<h1>Schemas</h1>
22
<mat-accordion>
3-
<mat-expansion-panel *ngFor="let schema of schemas | keyvalue;" [id]="schema.value.anchorIdentifier" [expanded]="selectedSchema == schema.value.anchorIdentifier" (opened)="this.setSchemaSelection(schema.value)">
3+
<mat-expansion-panel *ngFor="let schema of schemas | keyvalue;" [id]="schema.value.anchorIdentifier.substr(1)" [expanded]="selectedSchema == schema.value.anchorIdentifier" (opened)="this.setSchemaSelection(schema.value)">
44
<mat-expansion-panel-header>
55
<mat-panel-title>
66
<h3>{{ schema.key }}</h3>

src/app/shared/models/schema.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Example } from './example.model';
33
export interface Schema {
44
name?: string;
55
description?: string;
6-
anchorIdentifier?: string;
6+
anchorIdentifier: string;
77
anchorUrl?: string;
88
type?: string;
99
format?: string;

tests/channel.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { test, expect } from '@playwright/test';
2+
import asyncApiJson from '../src/app/shared/mock/mock.springwolf-kafka-example.json'
3+
4+
test.describe('Channel', ()=> {
5+
test.beforeEach(async ({ page }, testInfo) => {
6+
console.log(`Running ${testInfo.title}`);
7+
await page.goto('http://localhost:4200/');
8+
});
9+
10+
test('first collapsible is rendered', async ({ page }) => {
11+
await page.locator("#channel-kafka-another-topic-publish-AnotherPayloadDto").click()
12+
await expect(page).toHaveURL('http://localhost:4200/#channel-kafka-another-topic-publish-AnotherPayloadDto');
13+
14+
await expect(page.getByRole('tabpanel', { name: 'Example' }).locator('textarea'))
15+
.toHaveValue(JSON.stringify(asyncApiJson.components.schemas.AnotherPayloadDto.example, null, 2))
16+
17+
await page.getByRole('tab', { name: 'Schema' }).getByText('Schema').click();
18+
await page.getByRole('heading', { name: 'AnotherPayloadDto #/components/schemas/AnotherPayloadDto' }).click();
19+
await page.getByRole('cell', { name: 'string Foo field example: "bar"' }).getByText('string').click();
20+
await page.getByRole('cell', { name: 'string Foo field example: "bar"' }).getByText('Foo field').click();
21+
await page.getByRole('cell', { name: 'string Foo field example: "bar"' }).getByText('example: "bar"').click();
22+
23+
await page.getByRole('tab', { name: 'Headers' }).getByText('Headers').click();
24+
await page.getByRole('heading', { name: 'HeadersNotDocumented #/components/schemas/HeadersNotDocumented' }).click();
25+
await expect(page.getByRole('tabpanel', { name: 'Headers' }).locator('textarea'))
26+
.toHaveValue(JSON.stringify(asyncApiJson.components.schemas.HeadersNotDocumented.example, null, 2))
27+
28+
await page.getByRole('tab', { name: 'Bindings' }).getByText('Bindings').click();
29+
await page.getByText(/\{\s+"groupId":\s+\{\s+"type":\s+"string",\s+"enum":\s+\[\s+"example-group-id"\s+\]\s+\}\s+\}/).click();
30+
});
31+
})

tests/header.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Header', ()=> {
4+
test.beforeEach(async ({ page }, testInfo) => {
5+
console.log(`Running ${testInfo.title}`);
6+
await page.goto('http://localhost:4200/');
7+
});
8+
9+
test('github url is shown', async ({ page }) => {
10+
await expect(page.locator("mat-toolbar a")).toHaveAttribute('href', 'https://github.com/stavshamir/springwolf')
11+
});
12+
})

tests/info.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { test, expect } from '@playwright/test';
2+
import asyncApiJson from '../src/app/shared/mock/mock.springwolf-kafka-example.json'
3+
4+
test.describe('Info', ()=> {
5+
test.beforeEach(async ({ page }, testInfo) => {
6+
console.log(`Running ${testInfo.title}`);
7+
await page.goto('http://localhost:4200/');
8+
});
9+
10+
test('section is shown', async ({ page }) => {
11+
await expect(page.locator('app-info h1')).toHaveText('Springwolf example project - Kafka' );
12+
await expect(page.locator('app-info h5')).toHaveText('API VERSION 1.0.0 - AsyncAPI JSON file' );
13+
await expect(page.locator('app-info p')).toHaveText('Springwolf example project to demonstrate springwolfs abilities' );
14+
});
15+
16+
test('download of AsyncApi json', async ({ page }) => {
17+
const [popup] = await Promise.all([
18+
page.waitForEvent('popup'),
19+
page.getByRole('link', { name: 'AsyncAPI JSON file' }).click()
20+
]);
21+
const popupContent = await popup.evaluate('document.body.textContent') as string
22+
await expect(JSON.parse(popupContent)).toStrictEqual(asyncApiJson)
23+
});
24+
})

0 commit comments

Comments
 (0)