Initial commit; adaptation from mascarpone
This commit is contained in:
commit
3d45ec4b0a
36 changed files with 5877 additions and 0 deletions
22
e2e/README.md
Normal file
22
e2e/README.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# e2e
|
||||
|
||||
Install deps with `corepack pnpm i`.
|
||||
|
||||
Ensure that if you update `@playwright/test` that
|
||||
(a) it remains a devdep, and
|
||||
(b) it is a `=`-type dependency.
|
||||
|
||||
Start a dev server with `cargo run`. Tests expect an ephemeral user with username and
|
||||
password both `test`. Achieve this with
|
||||
```
|
||||
cargo run set-password test
|
||||
```
|
||||
then
|
||||
```
|
||||
sqlite3 users.db "update users set ephemeral=true where username='test'"
|
||||
```
|
||||
|
||||
Run tests in the docker image with the right browsers installed with `./Taskfile
|
||||
playwright:local` or `./Taskfile playwright:ui`.
|
||||
|
||||
|
||||
47
e2e/Taskfile
Executable file
47
e2e/Taskfile
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env bash
|
||||
PATH=$PATH:node_modules/.bin
|
||||
SCRIPT_DIR=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)
|
||||
|
||||
_playwright_version() {
|
||||
jq -r '.devDependencies["@playwright/test"]' "$SCRIPT_DIR/package.json" | sed -e 's/\=/v/'
|
||||
}
|
||||
|
||||
playwright:local() {
|
||||
exec docker run \
|
||||
--interactive --tty --rm --ipc=host --net=host \
|
||||
--volume "$SCRIPT_DIR":/e2e:rw --env BASE_URL="$BASE_URL" \
|
||||
"mcr.microsoft.com/playwright:$(_playwright_version)" \
|
||||
bash -c "cd /e2e && env PROJECT_FILTER=firefox ./Taskfile _test $*"
|
||||
}
|
||||
|
||||
playwright:ui() {
|
||||
playwright:local --ui-host=0.0.0.0
|
||||
}
|
||||
|
||||
playwright:ci() {
|
||||
exec docker run \
|
||||
--interactive --tty --rm --ipc=host --net=host \
|
||||
--volume "$SCRIPT_DIR":/e2e:rw --env BASE_URL="$BASE_URL" \
|
||||
"mcr.microsoft.com/playwright:$(_playwright_version)" \
|
||||
bash -c "cd /e2e && ./Taskfile _test $*"
|
||||
}
|
||||
|
||||
_test:full() {
|
||||
if ! test -f /.dockerenv; then
|
||||
echo "Don't run _test directly; use playwright:local."
|
||||
fi
|
||||
|
||||
# run only in firefox first to see if there's errors and,
|
||||
# only if not, run in everything else
|
||||
env PROJECT_FILTER=firefox playwright test "$@" && \
|
||||
env PROJECT_FILTER=!firefox playwright test "$@"
|
||||
}
|
||||
_test() {
|
||||
if ! test -f /.dockerenv; then
|
||||
echo "Don't run _test directly; use playwright:local."
|
||||
fi
|
||||
|
||||
playwright test "$@"
|
||||
}
|
||||
|
||||
"$@"
|
||||
37
e2e/custom-expects.ts
Normal file
37
e2e/custom-expects.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { expect, type Locator } from '@playwright/test';
|
||||
expect.extend({
|
||||
async toBeAbove(self: Locator, other: Locator) {
|
||||
const name = 'toBeAbove';
|
||||
let pass: boolean;
|
||||
let matcherResult: any;
|
||||
let selfY: number | null = null;
|
||||
let otherY: number | null = null;
|
||||
try {
|
||||
selfY = (await self.boundingBox())?.y ?? null;
|
||||
otherY = (await self.boundingBox())?.y ?? null;
|
||||
pass = selfY !== null && otherY !== null && (selfY < otherY);
|
||||
} catch (e: any) {
|
||||
matcherResult = e.matcherResult;
|
||||
pass = false;
|
||||
}
|
||||
|
||||
if (this.isNot) {
|
||||
pass =!pass;
|
||||
}
|
||||
|
||||
const message = () => this.utils.matcherHint(name, undefined, undefined, { isNot: this.isNot }) +
|
||||
'\n\n' +
|
||||
`Locator: ${self}\n` +
|
||||
`Expected: above ${other} (y=${this.utils.printExpected(otherY)})\n` +
|
||||
(matcherResult ? `Received: y=${this.utils.printReceived(selfY)}` : '');
|
||||
|
||||
return {
|
||||
message,
|
||||
pass,
|
||||
name,
|
||||
expected: (this.isNot ? '>=' : '<') + otherY,
|
||||
actual: selfY,
|
||||
};
|
||||
|
||||
}
|
||||
});
|
||||
17
e2e/package.json
Normal file
17
e2e/package.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "entretien/e2e",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo use Taskfile instead"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "=1.57.0",
|
||||
"@types/node": "^24.9.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.28.1+sha512.7d7dbbca9e99447b7c3bf7a73286afaaf6be99251eb9498baefa7d406892f67b879adb3a1d7e687fc4ccc1a388c7175fbaae567a26ab44d1067b54fcb0d6a316"
|
||||
}
|
||||
11
e2e/pages/util.ts
Normal file
11
e2e/pages/util.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import type { Page } from '@playwright/test';
|
||||
|
||||
export const login = async (page: Page) => {
|
||||
await page.goto('/login');
|
||||
await page.getByLabel("Username").fill("test");
|
||||
await page.getByLabel("Password").fill("test");
|
||||
await page.getByRole("button", { name: /login/i }).click();
|
||||
await page.waitForURL('/');
|
||||
};
|
||||
|
||||
72
e2e/playwright.config.ts
Normal file
72
e2e/playwright.config.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { defineConfig, devices } from '@playwright/test';
|
||||
import './custom-expects';
|
||||
|
||||
// purposefully not using ??: we want to replace empty empty string with default
|
||||
const BASE_URL = process.env.BASE_URL || 'http://localhost:3000';
|
||||
|
||||
let addlConfig = {
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
};
|
||||
|
||||
let projects = [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'webkit',
|
||||
use: { ...devices['Desktop Safari'] },
|
||||
},
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
{
|
||||
name: 'Mobile Chrome',
|
||||
use: { ...devices['Pixel 5'] },
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Mobile Safari',
|
||||
use: { ...devices['iPhone 12'] },
|
||||
},
|
||||
];
|
||||
|
||||
const pfil = process.env.PROJECT_FILTER;
|
||||
if (pfil) {
|
||||
if (pfil.startsWith('!')) {
|
||||
projects = projects.filter(p => p.name !== pfil.slice(1));
|
||||
} else {
|
||||
projects = projects.filter(p => p.name === pfil);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: './pages',
|
||||
fullyParallel: true,
|
||||
workers: 1,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: Boolean(process.env.CI),
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: 'html',
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: BASE_URL,
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects,
|
||||
...addlConfig,
|
||||
});
|
||||
|
||||
67
e2e/pnpm-lock.yaml
generated
Normal file
67
e2e/pnpm-lock.yaml
generated
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
specifier: '=1.57.0'
|
||||
version: 1.57.0
|
||||
'@types/node':
|
||||
specifier: ^24.9.1
|
||||
version: 24.10.1
|
||||
|
||||
packages:
|
||||
|
||||
'@playwright/test@1.57.0':
|
||||
resolution: {integrity: sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
'@types/node@24.10.1':
|
||||
resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==}
|
||||
|
||||
fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
playwright-core@1.57.0:
|
||||
resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.57.0:
|
||||
resolution: {integrity: sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@playwright/test@1.57.0':
|
||||
dependencies:
|
||||
playwright: 1.57.0
|
||||
|
||||
'@types/node@24.10.1':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
fsevents@2.3.2:
|
||||
optional: true
|
||||
|
||||
playwright-core@1.57.0: {}
|
||||
|
||||
playwright@1.57.0:
|
||||
dependencies:
|
||||
playwright-core: 1.57.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
1
e2e/static
Symbolic link
1
e2e/static
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../static
|
||||
Loading…
Add table
Add a link
Reference in a new issue