Skip to content

Commit ac48853

Browse files
committed
Merge branch 'main' into feature/packaging
2 parents 8cfdc11 + 8e7963e commit ac48853

File tree

226 files changed

+9582
-17514
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

226 files changed

+9582
-17514
lines changed

.eslintignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
**/docs
77
**/node_modules
88
**/tests_output
9-
*.d.ts
9+
*.d.ts
10+
/.nx/

.eslintrc.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
"no-implied-eval": "error",
3838
"complexity": "warn",
3939
"max-depth": "warn",
40-
"max-lines": "warn",
41-
"max-lines-per-function": "warn"
40+
"max-lines": "error",
41+
"max-lines-per-function": "error"
4242
},
4343
"ignorePatterns": ["**/node_modules/**/*", "**/dist/**/*"],
4444
"settings": {

.github/workflows/publish-packages.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ jobs:
1212
outputs:
1313
matrix: ${{ steps.matrix.outputs.TAGS }}
1414
steps:
15-
- uses: actions/checkout@v2
15+
- uses: actions/checkout@v4
1616
with:
1717
ssh-key: ${{ secrets.MAIN_BOT_KEY_PRIVATE }}
18-
- uses: actions/setup-node@v3
18+
- uses: actions/setup-node@v4
1919
with:
20-
node-version: 18.13.0
20+
node-version: 20.16.0
2121
registry-url: https://registry.npmjs.org/
2222
- run: npm ci
2323
- run: |

.github/workflows/publish-pages.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ jobs:
99
deploy:
1010
runs-on: ubuntu-latest
1111
steps:
12-
- uses: actions/checkout@v2
13-
- uses: actions/setup-node@v3
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-node@v4
1414
with:
15-
node-version: 18.13.0
15+
node-version: 20.16.0
1616
registry-url: https://registry.npmjs.org/
1717
- run: npm ci
1818
- run: npm run pages:build

.github/workflows/run-tests.yml

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,60 @@
1-
name: Run linter and tests
1+
name: Run linter, tests and type check
22

33
on: push
44

55
jobs:
6-
lint-test:
6+
lint:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
- uses: actions/setup-node@v4
11+
with:
12+
node-version: 20.16.0
13+
registry-url: https://registry.npmjs.org/
14+
- run: |
15+
npm ci
16+
npm run lint:ci
17+
test:
718
runs-on: ubuntu-latest
819
steps:
920
- uses: actions/checkout@v2
1021
- uses: actions/setup-node@v3
1122
with:
12-
node-version: 18.13.0
23+
node-version: 20.16.0
1324
registry-url: https://registry.npmjs.org/
1425
- run: |
1526
npm ci
16-
npm run lint:ci
1727
npm run test
28+
teste2e:
29+
timeout-minutes: 60
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v4
33+
- uses: actions/setup-node@v4
34+
with:
35+
node-version: 20.16.0
36+
- name: Install dependencies
37+
run: npm ci
38+
- name: Build snowbox (started by playwright by itself)
39+
run: npm run snowbox:build
40+
- name: Install Playwright Browsers
41+
run: npx playwright install --with-deps
42+
- name: Run Playwright tests
43+
run: npm run test:e2e
44+
- uses: actions/upload-artifact@v4
45+
if: ${{ !cancelled() }}
46+
with:
47+
name: playwright-report
48+
path: playwright-report/
49+
retention-days: 30
50+
type-check:
51+
runs-on: ubuntu-latest
52+
steps:
53+
- uses: actions/checkout@v2
54+
- uses: actions/setup-node@v3
55+
with:
56+
node-version: 20.16.0
57+
registry-url: https://registry.npmjs.org/
58+
- run: |
59+
npm ci
60+
npm run tsc:ci

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ logs
1414
/.idea/
1515
/.nx/
1616
**/.parcel-cache
17-
.nx/cache
17+
/test-results/
18+
/playwright-report/
19+
/blob-report/
20+
/playwright/.cache/

.prettierignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
build
2-
dist
2+
dist
3+
/.nx/workspace-data

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Other clients with more specific code include the [Denkmalkarte Schleswig-Holste
5454
<table align="center">
5555
<tr align="center">
5656
<td align="center"><img src="./pages/assets/landessymbole/bremen.svg" alt="Bremer Wappenzeichen" height="120px" style="object-fit: contain;"><div>Freie Hansestadt Bremen</div></td>
57-
<td align="center"><img src="./pages/assets/landessymbole/hamburg.svg" alt="Hamburg-Symbol" height="120px" style="object-fit: contain;"><div>Freie Freie und Hansestadt Hamburg</div></td>
57+
<td align="center"><img src="./pages/assets/landessymbole/hamburg.svg" alt="Hamburg-Symbol" height="120px" style="object-fit: contain;"><div>Freie und Hansestadt Hamburg</div></td>
5858
</tr>
5959
<tr align="center">
6060
<td align="center"><img src="./pages/assets/landessymbole/sachsen-anhalt.svg" alt="Landessymbol Sachsen-Anhalt" height="120px" style="object-fit: contain;"><div>Sachsen-Anhalt</div></td>

__mocks__/jest.setup.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import 'regenerator-runtime/runtime'
2+
3+
class Worker {
4+
constructor(stringUrl) {
5+
this.url = stringUrl
6+
this.onmessage = () => {
7+
// empty
8+
}
9+
}
10+
11+
postMessage(msg) {
12+
this.onmessage(msg)
13+
}
14+
}
15+
// a mock for web worker
16+
window.Worker = Worker
17+
18+
window.URL.createObjectURL = function () {
19+
// empty
20+
}

e2e/draw.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { test, expect } from '@playwright/test'
2+
import { openSnowbox } from './utils/openSnowbox'
3+
4+
const drawTargetId = '#vuex-target-draw-result'
5+
6+
test('clicks to the map produce a fetchable pin coordinate', async ({
7+
page,
8+
}) => {
9+
await openSnowbox(page)
10+
11+
const canvas = await page.locator('canvas')
12+
const boundingBox = await canvas.boundingBox()
13+
if (boundingBox === null) throw new Error('Canvas not found.')
14+
const { width, height } = boundingBox
15+
let { x, y } = boundingBox
16+
17+
x += width / 2
18+
y += height / 2
19+
20+
await page.getByLabel('Draw tools').click()
21+
await page.getByText('Draw and write').click()
22+
await page.getByText('Polygon').click()
23+
24+
const moves: [number, number, string][] = [
25+
[0, 0, 'click'],
26+
[40, -40, 'click'],
27+
[40, 40, 'click'],
28+
[-80, 80, 'click'],
29+
[-80, -80, 'click'],
30+
[40, -40, 'dblclick'],
31+
]
32+
33+
for (const [xMove, yMove, method] of moves) {
34+
await page.mouse[method]((x += xMove), (y += yMove))
35+
}
36+
37+
const drawing = JSON.parse(await page.locator(drawTargetId).innerText())
38+
39+
expect(drawing.type).toBe('FeatureCollection')
40+
expect(drawing.features.length).toBe(1)
41+
expect(drawing.features[0].geometry.coordinates[0].length).toBe(7)
42+
})

e2e/pins.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { test, expect } from '@playwright/test'
2+
import { openSnowbox } from './utils/openSnowbox'
3+
4+
const pinsTargetId = '#vuex-target-pin-coordinate'
5+
6+
test('clicks to the map produce a fetchable pin coordinate', async ({
7+
page,
8+
}) => {
9+
await openSnowbox(page)
10+
11+
const coordinateTarget = page.locator(pinsTargetId)
12+
13+
await expect(coordinateTarget).toBeEmpty()
14+
await page.locator('canvas').click()
15+
await expect(coordinateTarget).toHaveText(/\d+(\.\d+)?,\d+(\.\d+)?/)
16+
})

e2e/toast.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { test, expect } from '@playwright/test'
2+
import { openSnowbox } from './utils/openSnowbox'
3+
import { dispatch } from './utils/vuex'
4+
5+
const locatable = '私が来た'
6+
7+
test('programmatically dispatched toasts are visible in the UI', async ({
8+
page,
9+
}) => {
10+
await openSnowbox(page)
11+
12+
await dispatch(page, 'plugin/toast/addToast', {
13+
type: 'info',
14+
text: locatable,
15+
})
16+
17+
await expect(page.getByText(locatable)).toBeVisible()
18+
})

e2e/utils/clickTimes.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Page } from '@playwright/test'
2+
3+
export const clickTimes = async ({
4+
page,
5+
value,
6+
times,
7+
method = 'getByLabel',
8+
}: {
9+
page: Page
10+
value: string
11+
times: number
12+
method?: string
13+
}) => {
14+
for (let i = 0; i < times; i++) {
15+
await page[method](value).click()
16+
}
17+
}

e2e/utils/openSnowbox.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Page } from '@playwright/test'
2+
3+
export const openSnowbox = async (page: Page) => {
4+
// @ts-expect-error | it's manually added in snowbox client
5+
const watchReadiness = page.waitForFunction(() => Boolean(window.mapInstance))
6+
await page.goto('./dist/index.html')
7+
await watchReadiness
8+
}

e2e/utils/vuex.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { Page } from '@playwright/test'
2+
3+
const execute = async (
4+
page: Page,
5+
command: string,
6+
path: string,
7+
payload: unknown,
8+
params?: object
9+
) => {
10+
const evaluatable = `window.mapInstance.$store.${command}('${path}'${
11+
typeof payload !== 'undefined'
12+
? `, ${JSON.stringify(payload)}`
13+
: typeof params !== 'undefined'
14+
? JSON.stringify(null)
15+
: ''
16+
}${typeof params !== 'undefined' ? `, ${JSON.stringify(params)}` : ''})`
17+
console.error(evaluatable)
18+
await page.evaluate(evaluatable)
19+
}
20+
21+
export const dispatch = async (
22+
page: Page,
23+
path: string,
24+
payload: unknown,
25+
params?: object
26+
) => await execute(page, 'dispatch', path, payload, params)
27+
28+
export const commit = async (
29+
page: Page,
30+
path: string,
31+
payload: unknown,
32+
params?: object
33+
) => await execute(page, 'commit', path, payload, params)

e2e/zoom.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { test, expect } from '@playwright/test'
2+
import { openSnowbox } from './utils/openSnowbox'
3+
import { clickTimes } from './utils/clickTimes'
4+
5+
const zoomTargetId = '#vuex-target-zoom'
6+
7+
test('zoom in button zooms in until max zoom', async ({ page }) => {
8+
const zoomInLabel = 'Zoom in'
9+
await openSnowbox(page)
10+
11+
const zoomTarget = page.locator(zoomTargetId)
12+
await expect(zoomTarget).toHaveText('2')
13+
await clickTimes({ page, value: zoomInLabel, times: 7 })
14+
await expect(zoomTarget).toHaveText('9')
15+
await expect(page.getByLabel(zoomInLabel)).toBeDisabled()
16+
})
17+
18+
test('zoom out button zooms out until min zoom', async ({ page }) => {
19+
const zoomOutLabel = 'Zoom out'
20+
await openSnowbox(page)
21+
22+
const zoomTarget = page.locator(zoomTargetId)
23+
await expect(zoomTarget).toHaveText('2')
24+
await clickTimes({ page, value: zoomOutLabel, times: 2 })
25+
await expect(zoomTarget).toHaveText('0')
26+
await expect(page.getByLabel(zoomOutLabel)).toBeDisabled()
27+
})

jest.config.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const config: Config.InitialOptions = {
55
'**/*.{js,ts,vue}',
66
'!**/(node_modules|build|dist|dist-test|.cache|coverage|docs|tests_output)/**',
77
],
8-
modulePathIgnorePatterns: ['<rootDir>/mpapi/'],
8+
modulePathIgnorePatterns: ['<rootDir>/mpapi/', '<rootDir>/e2e/'],
99
moduleFileExtensions: ['js', 'ts', 'json', 'vue'],
1010
moduleNameMapper: {
1111
'vuetify/lib': '<rootDir>/node_modules/vuetify/es5',
@@ -19,9 +19,11 @@ const config: Config.InitialOptions = {
1919
'^.+\\.tsx?$': 'ts-jest',
2020
'^.*\\.js$': 'babel-jest',
2121
},
22+
// jest-canvas-mock and setup file is required because of @masterportal/masterportalapi; setup file is based on setup file from @masterportal/masterportalapi setup
23+
setupFiles: ['jest-canvas-mock'],
24+
setupFilesAfterEnv: ['./__mocks__/jest.setup.js'],
2225
transformIgnorePatterns: [
23-
// TODO: Remove both geotiff and quick-lru once we upgraded masterportalapi; see https://github.com/geotiffjs/geotiff.js/issues/292 for more
24-
'/node_modules/(?!(@repositoryname/vuex-generators|geotiff|quick-lru|ol|@masterportal/masterportalapi)/)',
26+
'/node_modules/(?!(@repositoryname/vuex-generators|@masterportal/masterportalapi|ol|geotiff|quick-lru|color-(space|parse|rgba|name))/)',
2527
],
2628
}
2729

0 commit comments

Comments
 (0)