diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3a70933799..572a8ecaf8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,9 @@ on: jobs: test-siteplan: runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/playwright:v1.61.1-noble + options: --ipc=host steps: - uses: actions/checkout@v7 @@ -24,10 +27,6 @@ jobs: run: npm ci working-directory: web/siteplan - - name: Install Playwright Browsers - run: npm exec playwright install --with-deps - working-directory: web/siteplan - - name: Run Playwright tests run: npm run test:e2e working-directory: web/siteplan diff --git a/web/siteplan/package.json b/web/siteplan/package.json index 4a4a3e4fef..90070d57bc 100644 --- a/web/siteplan/package.json +++ b/web/siteplan/package.json @@ -9,7 +9,10 @@ "build": "vite build --mode development", "build-prod": "vite build --mode production", "lint": "eslint src", - "test:e2e": "playwright test" + "test:e2e": "playwright test", + "test:e2e:docker": "docker run --rm --ipc=host -v .:/app -v /app/node_modules -w /app mcr.microsoft.com/playwright:v1.61.1-noble", + "test:e2e:run": "npm run test:e2e:docker -- bash -c 'npm ci && npm run test:e2e'", + "test:e2e:update": "npm run test:e2e:docker -- bash -c 'npm ci && npm run test:e2e -- -u'" }, "dependencies": { "@turf/boolean-disjoint": "^7.3.5", diff --git a/web/siteplan/playwright.config.ts b/web/siteplan/playwright.config.ts index c0ad874288..873aae7b1b 100644 --- a/web/siteplan/playwright.config.ts +++ b/web/siteplan/playwright.config.ts @@ -10,7 +10,7 @@ export default defineConfig({ /* Fail the build on CI if you accidentally left test.only in the source code. */ forbidOnly: !!process.env.CI, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, + workers: process.env.CI ? 1 : 3, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: 'html', diff --git a/web/siteplan/tests/measure.spec.ts b/web/siteplan/tests/measure.spec.ts new file mode 100644 index 0000000000..3115da4c07 --- /dev/null +++ b/web/siteplan/tests/measure.spec.ts @@ -0,0 +1,19 @@ +import { expect, test } from '@playwright/test' +import { loadSiteplan } from './utils' + +test('measure distance between two points', async ({ page }) => { + await loadSiteplan(page) + + await page.getByTitle('Messwerkzeug').click() + + await expect(page).toHaveScreenshot('measure-initial.png') + + await page.mouse.click(400, 400) + await page.mouse.dblclick(800, 400) + + await expect(page).toHaveScreenshot('measure.png') + + await page.getByTitle('Messwerkzeug').click() + + await expect(page).toHaveScreenshot('measure-initial.png') +}) diff --git a/web/siteplan/tests/measure.spec.ts-snapshots/measure-chromium-linux.png b/web/siteplan/tests/measure.spec.ts-snapshots/measure-chromium-linux.png new file mode 100644 index 0000000000..b1b92d6af7 Binary files /dev/null and b/web/siteplan/tests/measure.spec.ts-snapshots/measure-chromium-linux.png differ diff --git a/web/siteplan/tests/measure.spec.ts-snapshots/measure-initial-chromium-linux.png b/web/siteplan/tests/measure.spec.ts-snapshots/measure-initial-chromium-linux.png new file mode 100644 index 0000000000..e8bce0993a Binary files /dev/null and b/web/siteplan/tests/measure.spec.ts-snapshots/measure-initial-chromium-linux.png differ diff --git a/web/siteplan/tests/popup.spec.ts b/web/siteplan/tests/popup.spec.ts new file mode 100644 index 0000000000..5417519359 --- /dev/null +++ b/web/siteplan/tests/popup.spec.ts @@ -0,0 +1,20 @@ +import { expect, test } from '@playwright/test' +import { loadSiteplan } from './utils' + +test('show popup on object click', async ({ page }) => { + await loadSiteplan(page) + + await page.waitForTimeout(1000) + + await page.mouse.click(800, 350) + await expect(page.getByText('PZB: Keine Bezeichnung')).toBeVisible() + + await page.getByText('PZB: Keine Bezeichnung').click() + await expect(page.getByText('GUID: AB6A6068-9DDF-4F60-8CD1-053A034A2562')).toBeVisible() + + await page.locator('#popup-back').click() + await expect(page.locator('#featureInfoPopup')).toBeVisible() + + await page.locator('.popup-close').click() + await expect(page.locator('#featureInfoPopup')).not.toBeVisible() +}) diff --git a/web/siteplan/tests/pphn.spec.ts b/web/siteplan/tests/pphn.spec.ts index 2c14e53755..78a7abcb93 100644 --- a/web/siteplan/tests/pphn.spec.ts +++ b/web/siteplan/tests/pphn.spec.ts @@ -1,45 +1,28 @@ -import { expect, Page, test } from '@playwright/test' -import configuration from '../public/configuration.json' with { type: 'json' } -import pphn from './data/PPHN_1.10.0.3_01-02_Ibn-Z._-_2._AeM_2022-05-17_13-44_tg3.json' with { type: 'json' } - -async function loadSiteplan (page: Page) { - await page.route('*/**/siteplan.json', async route => { - await route.fulfill({ json: pphn }) - }) - - await page.goto('/') - // ensure that no .loading animation is there anymore - await expect(page.locator('.loading')).not.toBeVisible({ timeout: 10_000 }) -} - -const screenshotOptions = (page: Page) => ({ - mask: [page.locator('.rotate-control-container, .center-route-control-container')] -}) +import { expect, test } from '@playwright/test' +import { loadSiteplan, setDevelopmentMode } from './utils' test('initial loading', async ({ page }) => { await loadSiteplan(page) // Move to home button to get hover effect like "total view displaying" test await page.mouse.move(0, 0) - await expect(page).toHaveScreenshot('pphn-initial-view.png', screenshotOptions(page)) + await expect(page).toHaveScreenshot('pphn-initial-view.png') }) test('total view displaying', async ({ page }) => { await loadSiteplan(page) await page.getByRole('button', { name: '▣' }).click() - await expect(page).toHaveScreenshot('pphn-total-view.png', screenshotOptions(page)) + await expect(page).toHaveScreenshot('pphn-total-view.png') await page.getByRole('button', { name: '⦻' }).click() await page.mouse.move(0, 0) // move mouse to upper left corner again to get remove hover effect from center button - await expect(page).toHaveScreenshot('pphn-initial-view.png', screenshotOptions(page)) + await expect(page).toHaveScreenshot('pphn-initial-view.png') }) test('no development mode', async ({ page }) => { - await page.route('*/**/configuration.json', async route => { - await route.fulfill({ json: { ...configuration, developmentMode: false } }) - }) + await setDevelopmentMode(page, false) await loadSiteplan(page) - await expect(page).toHaveScreenshot('pphn-no-development-mode.png', screenshotOptions(page)) + await expect(page).toHaveScreenshot('pphn-no-development-mode.png') }) diff --git a/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-initial-view-chromium-linux.png b/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-initial-view-chromium-linux.png index 45c1c1986b..8cbf8b9474 100644 Binary files a/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-initial-view-chromium-linux.png and b/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-initial-view-chromium-linux.png differ diff --git a/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-no-development-mode-chromium-linux.png b/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-no-development-mode-chromium-linux.png index b359d2ac65..98720594ae 100644 Binary files a/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-no-development-mode-chromium-linux.png and b/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-no-development-mode-chromium-linux.png differ diff --git a/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-total-view-chromium-linux.png b/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-total-view-chromium-linux.png index 581fb4547f..5dc264b04a 100644 Binary files a/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-total-view-chromium-linux.png and b/web/siteplan/tests/pphn.spec.ts-snapshots/pphn-total-view-chromium-linux.png differ diff --git a/web/siteplan/tests/scale.spec.ts b/web/siteplan/tests/scale.spec.ts new file mode 100644 index 0000000000..06b20bd293 --- /dev/null +++ b/web/siteplan/tests/scale.spec.ts @@ -0,0 +1,13 @@ +import { expect, test } from '@playwright/test' +import { loadSiteplan } from './utils' + +test('use scale bar', async ({ page }) => { + await loadSiteplan(page) + + await expect(page.locator('.ol-scale-text')).toHaveText('1 : 1,000') + + await page.mouse.move(500, 500) + await page.mouse.wheel(0, 1000) + + await expect(page.locator('.ol-scale-text')).toHaveText('1 : 2,000') +}) diff --git a/web/siteplan/tests/search.spec.ts b/web/siteplan/tests/search.spec.ts new file mode 100644 index 0000000000..db9514febb --- /dev/null +++ b/web/siteplan/tests/search.spec.ts @@ -0,0 +1,27 @@ +import { expect, test } from '@playwright/test' +import { loadSiteplan } from './utils' + +test('find search results', async ({ page }) => { + await loadSiteplan(page) + const searchBar = page.getByRole('textbox') + await searchBar.click() + await searchBar.fill('C4C2FC46-CA76-46D0-87DD-FB158441603C') + + await searchBar.press('Enter') + await expect(page).toHaveScreenshot('search-result-one.png') + + await searchBar.press('Enter') + await expect(page).toHaveScreenshot('search-result-two.png') + + await searchBar.press('Enter') + await expect(page).toHaveScreenshot('search-result-three.png') + + await searchBar.press('Enter') + await expect(page).toHaveScreenshot('search-result-four.png') + + await searchBar.press('Enter') + await expect(page).toHaveScreenshot('search-result-one-again.png') + + await searchBar.press('Enter') + await expect(page).toHaveScreenshot('search-result-two.png') +}) diff --git a/web/siteplan/tests/search.spec.ts-snapshots/search-result-four-chromium-linux.png b/web/siteplan/tests/search.spec.ts-snapshots/search-result-four-chromium-linux.png new file mode 100644 index 0000000000..36ac2398f3 Binary files /dev/null and b/web/siteplan/tests/search.spec.ts-snapshots/search-result-four-chromium-linux.png differ diff --git a/web/siteplan/tests/search.spec.ts-snapshots/search-result-one-again-chromium-linux.png b/web/siteplan/tests/search.spec.ts-snapshots/search-result-one-again-chromium-linux.png new file mode 100644 index 0000000000..d590c361b5 Binary files /dev/null and b/web/siteplan/tests/search.spec.ts-snapshots/search-result-one-again-chromium-linux.png differ diff --git a/web/siteplan/tests/search.spec.ts-snapshots/search-result-one-chromium-linux.png b/web/siteplan/tests/search.spec.ts-snapshots/search-result-one-chromium-linux.png new file mode 100644 index 0000000000..d3994d9cea Binary files /dev/null and b/web/siteplan/tests/search.spec.ts-snapshots/search-result-one-chromium-linux.png differ diff --git a/web/siteplan/tests/search.spec.ts-snapshots/search-result-three-chromium-linux.png b/web/siteplan/tests/search.spec.ts-snapshots/search-result-three-chromium-linux.png new file mode 100644 index 0000000000..85a30b717c Binary files /dev/null and b/web/siteplan/tests/search.spec.ts-snapshots/search-result-three-chromium-linux.png differ diff --git a/web/siteplan/tests/search.spec.ts-snapshots/search-result-two-chromium-linux.png b/web/siteplan/tests/search.spec.ts-snapshots/search-result-two-chromium-linux.png new file mode 100644 index 0000000000..ad5071df18 Binary files /dev/null and b/web/siteplan/tests/search.spec.ts-snapshots/search-result-two-chromium-linux.png differ diff --git a/web/siteplan/tests/sideinfo.spec.ts b/web/siteplan/tests/sideinfo.spec.ts new file mode 100644 index 0000000000..575665ab5d --- /dev/null +++ b/web/siteplan/tests/sideinfo.spec.ts @@ -0,0 +1,47 @@ +import { expect, Page, test } from '@playwright/test' +import { loadSiteplan, setDevelopmentMode } from './utils' + +async function expectScreenshot (page: Page, name: string) { + await expect(page.locator('#side-info-container')).toHaveScreenshot(`${name}-side-info.png`) +} + +test('show map selection', async ({ page }) => { + await setDevelopmentMode(page, true) + await loadSiteplan(page) + + await page.getByTitle('Kartenquelle').click() + + await expect(page.locator('.map-container')).toBeVisible() + await expectScreenshot(page, 'map-container') +}) + +test('show layer control', async ({ page }) => { + await setDevelopmentMode(page, true) + await loadSiteplan(page) + + await page.getByTitle('Ebenen verwalten').click() + + await expect(page.getByRole('heading', { name: 'Hinweis:' })).toBeVisible() + await expectScreenshot(page, 'layer-control') +}) + +test('show model summary control', async ({ page }) => { + await setDevelopmentMode(page, true) + await loadSiteplan(page) + + await page.getByTitle('Zusammenfassung').click() + + await expect(page.getByText('[Hinzugefügt, Unverändert, Entfernt, Geändert')).toBeVisible() + await expect(page.getByText('Bahnsteige:')).toBeVisible() + await expectScreenshot(page, 'model-summary') +}) + +test('show settings control', async ({ page }) => { + await setDevelopmentMode(page, true) + await loadSiteplan(page) + + await page.getByRole('button', { name: 'settings' }).click() + + await expect(page.getByText('Einstellungen')).toBeVisible() + await expectScreenshot(page, 'settings') +}) diff --git a/web/siteplan/tests/sideinfo.spec.ts-snapshots/layer-control-side-info-chromium-linux.png b/web/siteplan/tests/sideinfo.spec.ts-snapshots/layer-control-side-info-chromium-linux.png new file mode 100644 index 0000000000..a59b1b6140 Binary files /dev/null and b/web/siteplan/tests/sideinfo.spec.ts-snapshots/layer-control-side-info-chromium-linux.png differ diff --git a/web/siteplan/tests/sideinfo.spec.ts-snapshots/map-container-side-info-chromium-linux.png b/web/siteplan/tests/sideinfo.spec.ts-snapshots/map-container-side-info-chromium-linux.png new file mode 100644 index 0000000000..7b8d31ce9c Binary files /dev/null and b/web/siteplan/tests/sideinfo.spec.ts-snapshots/map-container-side-info-chromium-linux.png differ diff --git a/web/siteplan/tests/sideinfo.spec.ts-snapshots/model-summary-side-info-chromium-linux.png b/web/siteplan/tests/sideinfo.spec.ts-snapshots/model-summary-side-info-chromium-linux.png new file mode 100644 index 0000000000..91132f3b90 Binary files /dev/null and b/web/siteplan/tests/sideinfo.spec.ts-snapshots/model-summary-side-info-chromium-linux.png differ diff --git a/web/siteplan/tests/sideinfo.spec.ts-snapshots/settings-side-info-chromium-linux.png b/web/siteplan/tests/sideinfo.spec.ts-snapshots/settings-side-info-chromium-linux.png new file mode 100644 index 0000000000..c1548e6ef8 Binary files /dev/null and b/web/siteplan/tests/sideinfo.spec.ts-snapshots/settings-side-info-chromium-linux.png differ diff --git a/web/siteplan/tests/svg-catalog.spec.ts b/web/siteplan/tests/svg-catalog.spec.ts new file mode 100644 index 0000000000..60953ec112 --- /dev/null +++ b/web/siteplan/tests/svg-catalog.spec.ts @@ -0,0 +1,18 @@ +import { expect, test } from '@playwright/test' +import { loadSiteplan } from './utils' + +test('show svg katalog', async ({ page }) => { + await loadSiteplan(page) + + await page.getByText('Symbolkatalog').click() + + await expect(page).toHaveScreenshot('svg-katalog.png') + await expect(page.getByText('Symbolgruppe auswählen')).toBeVisible() + + await page.getByText('☰').click() + await page.getByText('Einzelnes Signal').click() + + await expect(page.getByText('Symbolgruppe auswählen')).not.toBeVisible() +}) + +// TODO: Test all the symbols and signal constellations diff --git a/web/siteplan/tests/svg-catalog.spec.ts-snapshots/svg-katalog-chromium-linux.png b/web/siteplan/tests/svg-catalog.spec.ts-snapshots/svg-katalog-chromium-linux.png new file mode 100644 index 0000000000..0f9ebcfad5 Binary files /dev/null and b/web/siteplan/tests/svg-catalog.spec.ts-snapshots/svg-katalog-chromium-linux.png differ diff --git a/web/siteplan/tests/utils.ts b/web/siteplan/tests/utils.ts new file mode 100644 index 0000000000..189ab09d13 --- /dev/null +++ b/web/siteplan/tests/utils.ts @@ -0,0 +1,21 @@ +import { Page } from '@playwright/test' +import configuration from '../public/configuration.json' with { type: 'json' } +import pphn from './data/PPHN_1.10.0.3_01-02_Ibn-Z._-_2._AeM_2022-05-17_13-44_tg3.json' with { type: 'json' } + +export async function setDevelopmentMode (page: Page, developmentMode: boolean) { + await page.route('*/**/configuration.json', async route => { + await route.fulfill({ json: { ...configuration, developmentMode } }) + }) +} + +export async function loadSiteplan (page: Page) { + await page.route('*/**/siteplan.json', async route => { + await route.fulfill({ json: pphn }) + }) + + await page.goto('/') + // ensure that .loading shows up and disappears again + await page.locator('.loading').waitFor({ state: 'visible', timeout: 10_000 }) + + await page.locator('.loading').waitFor({ state: 'hidden', timeout: 10_000 }) +}