test(playwright): add playwright report to track changes + correct playwright parameters
ci: fix actions/checkout@v6 → @v4 (v6 does not exist) GitHub started rejecting invalid action versions at parse time, causing every CI run to fail with 0s / 'workflow file issue' before any jobs could start. * test(e2e): only no retry * test(e2e): use static name in tests to facilitate screenshot comparaison * test(e2e): update linux screenshots * test(e2e): adapt test due to user-vignette generation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -81,7 +81,7 @@ jobs:
|
|||||||
if: needs.changes.outputs.backend == 'true'
|
if: needs.changes.outputs.backend == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
@@ -93,7 +93,7 @@ jobs:
|
|||||||
if: needs.changes.outputs.backend == 'true'
|
if: needs.changes.outputs.backend == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
components: clippy
|
components: clippy
|
||||||
@@ -120,7 +120,7 @@ jobs:
|
|||||||
--health-timeout 5s
|
--health-timeout 5s
|
||||||
--health-retries 5
|
--health-retries 5
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ jobs:
|
|||||||
if: needs.changes.outputs.backend == 'true'
|
if: needs.changes.outputs.backend == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
- uses: rustsec/audit-check@v2.0.0
|
- uses: rustsec/audit-check@v2.0.0
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -150,7 +150,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
- run: cargo build --release
|
- run: cargo build --release
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test"
|
DATABASE_URL: "postgres://postgres:postgres@localhost/oxicloud_test"
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Build the exact tag behind the published release or manual dispatch.
|
# Build the exact tag behind the published release or manual dispatch.
|
||||||
ref: ${{ github.event.inputs.version || github.event.release.tag_name || github.ref }}
|
ref: ${{ github.event.inputs.version || github.event.release.tag_name || github.ref }}
|
||||||
@@ -61,7 +61,7 @@ jobs:
|
|||||||
needs: test
|
needs: test
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
# Build the exact tag behind the published release or manual dispatch.
|
# Build the exact tag behind the published release or manual dispatch.
|
||||||
ref: ${{ github.event.inputs.version || github.event.release.tag_name || github.ref }}
|
ref: ${{ github.event.inputs.version || github.event.release.tag_name || github.ref }}
|
||||||
|
|||||||
@@ -26,11 +26,17 @@ jobs:
|
|||||||
- name: Install Node dependencies
|
- name: Install Node dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Build OxiCloud (release)
|
||||||
|
working-directory: .
|
||||||
|
run: cargo build --release
|
||||||
|
|
||||||
- name: Install Playwright browsers
|
- name: Install Playwright browsers
|
||||||
run: npx playwright install --with-deps
|
run: npx playwright install --with-deps
|
||||||
|
|
||||||
- name: Update snapshots
|
- name: Update snapshots
|
||||||
run: npm test -- --update-snapshots
|
run: npm test -- --update-snapshots
|
||||||
|
env:
|
||||||
|
BUILD_TARGET: release
|
||||||
|
|
||||||
- name: Commit updated snapshots
|
- name: Commit updated snapshots
|
||||||
uses: stefanzweifel/git-auto-commit-action@v5
|
uses: stefanzweifel/git-auto-commit-action@v5
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ charts/*/charts/*
|
|||||||
# Playwright
|
# Playwright
|
||||||
tests/e2e/node_modules/
|
tests/e2e/node_modules/
|
||||||
tests/e2e/test-results/
|
tests/e2e/test-results/
|
||||||
tests/e2e/playwright-report/
|
|
||||||
tests/e2e/blob-report/
|
tests/e2e/blob-report/
|
||||||
tests/e2e/playwright/.cache/
|
tests/e2e/playwright/.cache/
|
||||||
tests/e2e/playwright/.auth/
|
tests/e2e/playwright/.auth/
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"pretest": "bash ../common/spawn-db.sh",
|
"pretest": "bash ../common/spawn-db.sh",
|
||||||
"test": "npx playwright test --reporter=line,github --trace=on-first-retry scenarios/01-home-and-login.spec.ts scenarios/02-folder-management.spec.ts",
|
"test": "FORCE_COLOR=true npx playwright test scenarios/01-home-and-login.spec.ts scenarios/02-folder-management.spec.ts",
|
||||||
"posttest": "bash ../common/stop-db.sh"
|
"posttest": "bash ../common/stop-db.sh"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ export default defineConfig({
|
|||||||
testDir: './scenarios',
|
testDir: './scenarios',
|
||||||
fullyParallel: false,
|
fullyParallel: false,
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
retries: process.env.CI ? 2 : 0,
|
retries: 0,
|
||||||
workers: 1,
|
workers: 1,
|
||||||
reporter: process.env.CI ? [['github'], ['html']] : 'html',
|
reporter: process.env.CI ? [['line'], ['github'], ['html']] : [ ['list'], ['html']],
|
||||||
|
|
||||||
globalSetup: require.resolve('./global-setup'),
|
globalSetup: require.resolve('./global-setup'),
|
||||||
globalTeardown: require.resolve('./global-teardown'),
|
globalTeardown: require.resolve('./global-teardown'),
|
||||||
@@ -37,6 +37,9 @@ export default defineConfig({
|
|||||||
use: {
|
use: {
|
||||||
baseURL: 'http://localhost:8087',
|
baseURL: 'http://localhost:8087',
|
||||||
trace: 'on-first-retry',
|
trace: 'on-first-retry',
|
||||||
|
headless: true,
|
||||||
|
// take a screenshot on failure
|
||||||
|
screenshot: 'only-on-failure',
|
||||||
},
|
},
|
||||||
|
|
||||||
expect: {
|
expect: {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ test.describe('Folder management', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('folder creation', async ({ page }) => {
|
test('folder creation', async ({ page }) => {
|
||||||
const name = `Test folder ${Date.now()}`;
|
const name = `Test folder creation`;
|
||||||
|
|
||||||
await submitNewFolder(page, name);
|
await submitNewFolder(page, name);
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ test.describe('Folder management', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('folder reject if already exists', async ({ page }) => {
|
test('folder reject if already exists', async ({ page }) => {
|
||||||
const name = `Test folder ${Date.now()}`;
|
const name = `Test existing folder`;
|
||||||
|
|
||||||
// Prerequisite: create the folder once successfully.
|
// Prerequisite: create the folder once successfully.
|
||||||
await submitNewFolder(page, name);
|
await submitNewFolder(page, name);
|
||||||
@@ -122,9 +122,8 @@ test.describe('Folder management', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('folder rename', async ({ page }) => {
|
test('folder rename', async ({ page }) => {
|
||||||
const ts = Date.now();
|
const original = `Test folder`;
|
||||||
const original = `Test folder ${ts}`;
|
const renamed = `Renamed folders`;
|
||||||
const renamed = `Renamed folder ${ts}`;
|
|
||||||
|
|
||||||
// Prerequisite: create the folder to rename.
|
// Prerequisite: create the folder to rename.
|
||||||
await submitNewFolder(page, original);
|
await submitNewFolder(page, original);
|
||||||
|
|||||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 62 KiB |
@@ -7,7 +7,17 @@ export const TEST_ADMIN = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log in as the test admin and wait until the main app is ready.
|
* Log in as the test admin and wait until the main app is fully initialized.
|
||||||
|
*
|
||||||
|
* We wait for two things after the login redirect:
|
||||||
|
* 1. `#sidebar` — confirms the main HTML has loaded.
|
||||||
|
* 2. `#user-avatar-btn .user-vignette` — confirms that `setupUserMenu()` has
|
||||||
|
* run and mounted the avatar vignette. This is the earliest reliable
|
||||||
|
* signal that the click-handler on the avatar button is attached, so any
|
||||||
|
* subsequent test that opens the user menu will not race against JS startup.
|
||||||
|
*
|
||||||
|
* Without (2), CI (Ubuntu + Xvfb) occasionally clicks the button before the
|
||||||
|
* event listener is registered because the JS runtime is slower than on macOS.
|
||||||
*/
|
*/
|
||||||
export async function loginAsAdmin(page: Page) {
|
export async function loginAsAdmin(page: Page) {
|
||||||
await goToLoginPage(page);
|
await goToLoginPage(page);
|
||||||
@@ -15,6 +25,8 @@ export async function loginAsAdmin(page: Page) {
|
|||||||
await page.locator('#login-password').fill(TEST_ADMIN.password);
|
await page.locator('#login-password').fill(TEST_ADMIN.password);
|
||||||
await page.locator('#login-panel button[type="submit"]').click();
|
await page.locator('#login-panel button[type="submit"]').click();
|
||||||
await expect(page.locator('#sidebar')).toBeVisible({ timeout: 15_000 });
|
await expect(page.locator('#sidebar')).toBeVisible({ timeout: 15_000 });
|
||||||
|
// Wait for the JS app to initialise: avatar vignette present ⟹ click handler attached.
|
||||||
|
await expect(page.locator('#user-avatar-btn .user-vignette')).toBeAttached({ timeout: 10_000 });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user