Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(playwright): setup and config #11836

Merged
merged 60 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
78e90f7
work in progress
framitdavid Dec 8, 2023
d18c5d7
config playwrigth
framitdavid Dec 11, 2023
68d833c
Merge branch 'master' into feat/playwright
framitdavid Dec 11, 2023
407b760
just for testing
framitdavid Dec 11, 2023
5f9d4e9
revert yml to use correct triggers for master
framitdavid Dec 11, 2023
164aa49
revert unreleated changes
framitdavid Dec 11, 2023
3628ce5
removed default test-examples
framitdavid Dec 11, 2023
2b7a99e
created shared auth-context
framitdavid Dec 11, 2023
4a9975f
clean ups and improve paths
framitdavid Dec 11, 2023
5d333e7
make playwright as standalone workspace package
framitdavid Dec 11, 2023
a3d34ec
update git ignore
framitdavid Dec 11, 2023
035e57f
set CI to true within the workflow
framitdavid Dec 12, 2023
864a52a
revert pre-commit
framitdavid Dec 12, 2023
dbd1b1c
delete file that should not be included in git
framitdavid Dec 12, 2023
cd1cf36
Merge branch 'master' into feat/playwright
framitdavid Dec 12, 2023
03e2f5e
added more e2e-tests
framitdavid Dec 13, 2023
5c0cd59
work in progress
framitdavid Dec 14, 2023
706357f
merge master into feature
framitdavid Dec 18, 2023
d4dbf1a
code clean ups and written a setup script
framitdavid Dec 19, 2023
225b620
prettier
framitdavid Dec 19, 2023
139c5a7
removed unsued code
framitdavid Dec 19, 2023
9731d40
removed dotenv package from global package and include within playwirght
framitdavid Dec 19, 2023
b74176a
revert some formatting
framitdavid Dec 19, 2023
2292b89
improved yml file
framitdavid Dec 19, 2023
9c15161
work in progress by extending the test options
framitdavid Dec 19, 2023
0187063
Merge branch 'master' into feat/playwright
framitdavid Dec 19, 2023
a82d2bd
implement support of parameterized tests
framitdavid Dec 19, 2023
295b5c4
added a comment to explain why we extends the test
framitdavid Dec 19, 2023
dcf298a
Merge branch 'master' into feat/playwright
framitdavid Dec 19, 2023
517cfa3
improved README.md
framitdavid Dec 19, 2023
deaeeaf
clean up setup.ts script
framitdavid Dec 19, 2023
7365ace
added support of teardown by deleting the app after test runs
framitdavid Dec 19, 2023
b4b78b6
refactor to keep things within feature-folders
framitdavid Dec 19, 2023
277252e
create script to make access-token to gitea
framitdavid Dec 19, 2023
2bf7aa8
updated the README.md file
framitdavid Dec 19, 2023
a90ebbd
docs
framitdavid Dec 19, 2023
eec4f3e
Merge branch 'master' into feat/playwright
framitdavid Dec 20, 2023
20190ae
updated jest.config to match *.test only
framitdavid Dec 20, 2023
f75813d
some code clean-ups
framitdavid Dec 20, 2023
209cd97
removed @types/node from root package.json
framitdavid Dec 20, 2023
f55cddf
merge master into branch
framitdavid Jan 3, 2024
d50a97b
yarn.lock
framitdavid Jan 3, 2024
010aef3
merge master into feature
framitdavid Jan 8, 2024
392d903
Fixed yarn.lock file
framitdavid Jan 8, 2024
b958fba
use gherkin-like syntax
framitdavid Jan 8, 2024
cf37b32
updated README.md and simplified setup
framitdavid Jan 8, 2024
5224007
revert tests to be like playwright native
framitdavid Jan 10, 2024
d7e3f45
update yml file
framitdavid Jan 10, 2024
c210f44
updated command for running tests
framitdavid Jan 10, 2024
625756e
update yml file
framitdavid Jan 10, 2024
d6fe40e
delete yml for now
framitdavid Jan 10, 2024
a0d96c8
Merge branch 'master' into feat/playwright
framitdavid Jan 10, 2024
d20facf
Merge branch 'master' into feat/playwright
framitdavid Jan 10, 2024
6bf8bab
PR-feedback
framitdavid Jan 12, 2024
b5b163a
Merge branch 'feat/playwright' of https://github.com/Altinn/altinn-st…
framitdavid Jan 12, 2024
f49fc88
Merge branch 'master' into feat/playwright
framitdavid Jan 12, 2024
72bf08d
PR feedback
framitdavid Jan 12, 2024
2f2a8dc
Merge branch 'feat/playwright' of https://github.com/Altinn/altinn-st…
framitdavid Jan 12, 2024
efbb8d7
Merge branch 'master' into feat/playwright
framitdavid Jan 12, 2024
f797050
Clarify that this page is not using the nb/en.json files for language
framitdavid Jan 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Playwright Tests
on:
push:
branches:
- master
paths:
- 'frontend/**'
- '.github/workflows/playwright.yml'
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: yarn
- name: Install Playwright Browsers
run: yarn playwright install --with-deps
- name: Run Playwright tests
run: yarn playwright-e2e
env:
PLAYWRIGHT_TEST_BASE_URL: "https://dev.altinn.studio"
PLAYWRIGHT_DESIGNER_APP_NAME: "auto-designer-app-dev"
CI: true
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,8 @@ stats.csv
.vscode/settings.json
.vscode/tasks.json
.vscode/launch.json
/test-results/
/blob-report/
/playwright/.cache/
/frontend/testing/playwright/playwright-report
.playwright/
1 change: 0 additions & 1 deletion frontend/testing/.eslintignore

This file was deleted.

1 change: 1 addition & 0 deletions frontend/testing/playwright/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# TODO WRITE DOCS!
16 changes: 16 additions & 0 deletions frontend/testing/playwright/helpers/BasePage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Routes } from './Routes';
Fixed Show fixed Hide fixed
import { Page } from '@playwright/test';
import { RouterRoute } from './RouterRoute';
import { Environment } from './StudioEnvironment';

export class BasePage extends RouterRoute {
public readonly _page: Page;

constructor(
private page: Page,
private environment: Environment,
) {
super(environment);
this._page = this.page;
}
}
36 changes: 36 additions & 0 deletions frontend/testing/playwright/helpers/RouterRoute.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Environment, StudioEnvironment } from './StudioEnvironment';

type SupportedRoutes = 'altinnLoginPage' | 'dashboard' | 'dashboardCreateApp' | 'editorOverview';

type RouterRoutes = Record<SupportedRoutes, string>;

export class RouterRoute extends StudioEnvironment {
private readonly routerRoutes: RouterRoutes = {
altinnLoginPage: '/',
dashboard: '/dashboard',
dashboardCreateApp: '/dashboard/self/new',
editorOverview: `/editor/{{org}}/{{app}}/overview`,
};

constructor(environment: Environment) {
super(environment);
}

public getRoute(route: SupportedRoutes): string {
const routerRoute: string = this.routerRoutes[route];

if (this.includesOrgAndApp(routerRoute)) {
return this.replaceOrgAndMap(routerRoute);
}

return this.routerRoutes[route];
}

private replaceOrgAndMap(route: string): string {
return route.replace('{{org}}', this.org).replace('{{app}}', this.app);
}

private includesOrgAndApp(route: string): boolean {
return route.includes('{{org}}') || route.includes('{{app}}');
}
}
15 changes: 15 additions & 0 deletions frontend/testing/playwright/helpers/StudioEnvironment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export type Environment = {
org: string;
app: string;
};

export class StudioEnvironment {
public readonly org: string;
public readonly app: string;
public readonly designerAppName: string;

constructor(private environment: Environment) {
this.org = this.environment?.org ?? process.env.PLAYWRIGHT_USER;
this.app = this.environment?.app ?? process.env.PLAYWRIGHT_DESIGNER_APP_NAME;
}
}
15 changes: 15 additions & 0 deletions frontend/testing/playwright/integration/auth.setup.ts
framitdavid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { test as setup } from '@playwright/test';
import { LoginPage } from "../pages/LoginPage";


setup('authenticate user', async ({page}) => {
const loginPage = new LoginPage(page);

await loginPage.goToAltinnLoginPage();
await loginPage.goToGiteaLoginPage();
await loginPage.writeUsername(process.env.PLAYWRIGHT_USER);
await loginPage.writePassword(process.env.PLAYWRIGHT_PASS);
await loginPage.clickLoginButton();
await loginPage.confirmSuccessfulLogin();
await loginPage.addSessionToSharableStorage();
})
13 changes: 13 additions & 0 deletions frontend/testing/playwright/integration/dashboard.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { test } from '@playwright/test';
import { DashboardPage } from '../pages/DashboardPage';

test('create app', async ({ page }): Promise<void> => {
const dashboardPage = new DashboardPage(page);

await dashboardPage.goToDashboard();
await dashboardPage.clickOnCreateAppLink();
await dashboardPage.confirmNavigationToCreateAppForm();
await dashboardPage.writeAppName(app);
await dashboardPage.clickOnCreateAppButton();
await dashboardPage.verifyCreateAppIsSuccessful();
});
12 changes: 12 additions & 0 deletions frontend/testing/playwright/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
framitdavid marked this conversation as resolved.
Show resolved Hide resolved
"name": "playwright-studio",
"private": true,
"version": "1.0.0",
"packageManager": "yarn@4.0.2",
"devDependencies": {
"@playwright/test": "^1.40.1"
},
"scripts": {
"test:all": "playwright test --config ./playwright.config.ts"
}
}
33 changes: 33 additions & 0 deletions frontend/testing/playwright/pages/DashboardPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { BasePage } from '../helpers/BasePage';
import { Page } from '@playwright/test';

export class DashboardPage extends BasePage {
constructor(page: Page) {
super(page);
}

public async goToDashboard(): Promise<void> {
await this._page.goto(this.getRoute('dashboard'));
await this._page.waitForURL(this.getRoute('dashboard'));
}

public async clickOnCreateAppLink(): Promise<void> {
await this._page.getByRole('link', { name: 'Opprett ny applikasjon' }).click();
}

public async confirmNavigationToCreateAppForm(): Promise<void> {
await this._page.waitForURL(this.getRoute('dashboardCreateApp'));
}

public async writeAppName(appName: string): Promise<void> {
await this._page.getByLabel('Navn').fill(appName);
}

public async clickOnCreateAppButton(): Promise<void> {
await this._page.getByRole('button', { name: 'Opprett applikasjon' }).click();
}

public async verifyCreateAppIsSuccessful(): Promise<void> {
await this._page.waitForURL(this.getRoute('editorOverview'));
}
}
38 changes: 38 additions & 0 deletions frontend/testing/playwright/pages/LoginPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Page } from '@playwright/test';
import { BasePage } from '../helpers/BasePage';

export class LoginPage extends BasePage {
private readonly _authStorageFile: string = '.playwright/auth/user.json';

constructor(page: Page) {
super(page);
}

public async goToAltinnLoginPage(): Promise<void> {
await this._page.goto(this.getRoute('altinnLoginPage'));
}

public async goToGiteaLoginPage(): Promise<void> {
await this._page.getByRole('button', { name: 'Logg inn' }).click();
}

public async writeUsername(username: string): Promise<void> {
return await this._page.getByLabel('Username or Email Address').fill(username);
}

public async writePassword(password: string): Promise<void> {
return await this._page.getByLabel('Password').fill(password);
}

public async clickLoginButton(): Promise<void> {
return await this._page.getByRole('button', { name: 'Sign In' }).click();
}

public async confirmSuccessfulLogin(): Promise<void> {
return this._page.waitForURL(this.getRoute('dashboard'));
}

public async addSessionToSharableStorage() {
return await this._page.context().storageState({ path: this._authStorageFile });
}
}
30 changes: 30 additions & 0 deletions frontend/testing/playwright/playwright.config.ts
framitdavid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { defineConfig, devices } from '@playwright/test';
import { config } from 'dotenv';

config();

export default defineConfig({
testDir: './integration',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
trace: 'on-first-retry'
},

projects: [
{ name: "setup", testMatch: /.*\.setup\.ts/ },
{
name: 'chromium',
dependencies: ['setup'],
use: {
...devices['Desktop Chrome'],
baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL,
storageState: '.playwright/auth/user.json',
headless: false
},
},
],
});
3 changes: 3 additions & 0 deletions frontend/testing/playwright/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../tsconfig.json"
}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
"@navikt/aksel-icons": "5.9.2",
"@tanstack/react-query": "5.4.3",
"@tanstack/react-query-devtools": "5.8.1",
"@types/dotenv": "^8.2.0",
"ajv": "8.12.0",
"ajv-formats": "2.1.1",
"dotenv": "^16.3.1",
"react-error-boundary": "^4.0.11",
"react-i18next": "13.3.1",
"react-router-dom": "6.18.0",
Expand All @@ -33,6 +35,7 @@
"@types/css-modules": "1.0.4",
"@types/jest": "29.5.7",
"@types/lodash-es": "4.17.10",
"@types/node": "^20.10.3",
"@types/react": "18.2.34",
"@types/react-dom": "18.2.14",
"@types/react-redux": "7.1.28",
Expand Down Expand Up @@ -101,7 +104,8 @@
"syncpack": "npx syncpack fix-mismatches && npx syncpack format && npx syncpack set-semver-ranges",
"test": "jest --maxWorkers=50% --config=frontend/jest.config.js",
"test:ci": "jest --ci --coverage --max-workers=2 --cacheDirectory=$(yarn config get cacheFolder) --config=frontend/jest.config.js",
"typecheck": "yarn workspaces foreach -A run typecheck"
"typecheck": "yarn workspaces foreach -A run typecheck",
"playwright:test:all": "yarn workspace playwright-studio test:all"
},
"syncpack": {
"semverRange": ""
Expand All @@ -116,6 +120,7 @@
"frontend/studio-root",
"frontend/testing/mockend",
"frontend/testing/cypress",
"frontend/testing/playwright",
"frontend/packages/schema-editor",
"frontend/packages/schema-model",
"frontend/packages/shared",
Expand Down
Loading
Loading