Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
35 changes: 33 additions & 2 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ jobs:
node-version: 20

- name: Install dependencies
run: cd web/siteplan && npm install
run: npm ci
working-directory: web/siteplan

- name: Eslint
run: cd web/siteplan && npm run lint
run: npm run lint
working-directory: web/siteplan

lint-textviewer:
runs-on: ubuntu-latest
Expand All @@ -71,3 +73,32 @@ jobs:
- name: Eslint
run: cd web/textviewer && npm run lint

test-siteplan:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- uses: actions/setup-node@v6
with:
node-version: 20

- name: Install dependencies
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

- uses: actions/upload-artifact@v6
if: ${{ !cancelled() }}
with:
name: playwright-report
path: web/siteplan/playwright-report/
retention-days: 1

10 changes: 9 additions & 1 deletion web/siteplan/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ dist/
public/siteplan.json
public/font
.vscode
.env
.env

# Playwright
node_modules/
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/playwright/.auth/
85 changes: 85 additions & 0 deletions web/siteplan/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion web/siteplan/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"serve": "vite --port 8080",
"build": "vite build --mode development",
"build-prod": "vite build --mode production",
"lint": "eslint src"
"lint": "eslint src",
"test:e2e": "playwright test"
},
"dependencies": {
"@turf/boolean-disjoint": "^7.3.1",
Expand All @@ -26,6 +27,7 @@
"vuex": "^4.1.0"
},
"devDependencies": {
"@playwright/test": "^1.57.0",
"@stylistic/eslint-plugin": "5.7.0",
"@types/geojson": "^7946.0.15",
"@typescript-eslint/eslint-plugin": "^8.53.0",
Expand Down
39 changes: 39 additions & 0 deletions web/siteplan/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { defineConfig, devices } from '@playwright/test'

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './tests',
/* Run tests in files in parallel */
fullyParallel: true,
/* 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,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',

use: {
/* Base URL to use in actions like `await page.goto('')`. */
baseURL: 'http://localhost:8080',

trace: process.env.CI ? 'retain-on-failure' : 'on',
video: process.env.CI ? 'retain-on-failure' : 'on'
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] }
}
],

/* Run your local dev server before starting the tests */
webServer: {
command: 'npm run serve',
url: 'http://localhost:8080',
reuseExistingServer: !process.env.CI
}
})
4 changes: 3 additions & 1 deletion web/siteplan/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Menubar from '@/components/toolbar/Menubar.vue'
import Toolbar from '@/components/toolbar/Toolbar.vue'
import axios from 'axios'
import { Options, Vue } from 'vue-class-component'
import SvgCatalogService from './service/SvgCatalogService'
import { store } from './store'
import Configuration from './util/Configuration'
import PlanProToolboxTest from './util/PlanProToolboxTest'
Expand Down Expand Up @@ -48,7 +49,8 @@ import { ToolboxConfiguration } from './util/ToolboxConfiguration'
.catch(() => {
console.warn('Siteplan Font not available')
})

// Wait until the svg catalog service is ready
await SvgCatalogService.getInstance().isReady()
// Download the toolbox configuration
await axios
.get<ToolboxConfiguration>('/configuration.json')
Expand Down
2 changes: 1 addition & 1 deletion web/siteplan/src/components/FeatureService.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default class FeatureService extends Vue {
unsubscribe: SubscribeOptions | undefined
map: Map = store.state.map
model: SiteplanModel | null = null
svgService: SvgService = new SvgService(axios)
svgService: SvgService = new SvgService()
listFeature: ILageplanFeature[] = []
inLODView = false
collisionService = new CollisionService(this.map)
Expand Down
3 changes: 1 addition & 2 deletions web/siteplan/src/components/SVG/Svg.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ import SvgKatalog from './SvgKatalog.vue'
import SvgSingleSignal from './SvgSingleSignal.vue'
import SvgService from '@/service/SvgService'
import SignalBruecker from './SignalBruecke.vue'
import axios from 'axios'
import { Options, Vue } from 'vue-class-component'
import { ISvgElement } from '@/model/SvgElement'

Expand Down Expand Up @@ -75,7 +74,7 @@ import { ISvgElement } from '@/model/SvgElement'
}
})
export default class Svg extends Vue {
svgService = new SvgService(axios)
svgService = new SvgService()
mode = ''
listSignalGroup = []
mastList: ISvgElement[] | null | undefined = []
Expand Down
3 changes: 1 addition & 2 deletions web/siteplan/src/feature/LageplanFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import Configuration from '@/util/Configuration'
import NamedFeatureLayer from '@/util/NamedFeatureLayer'
import { compare } from '@/util/ObjectExtension'
import SvgDraw from '@/util/SVG/Draw/SvgDraw'
import axios from 'axios'
import { Feature, Map as OlMap } from 'ol'
import { Extent, getHeight, getWidth } from 'ol/extent'
import Geometry from 'ol/geom/Geometry'
Expand Down Expand Up @@ -46,7 +45,7 @@ export interface ILageplanFeature {

export default abstract class LageplanFeature<T extends SiteplanObject> implements ILageplanFeature {
map: OlMap
svgService = new SvgService(axios)
svgService = new SvgService()
constructor (map: OlMap) {
this.map = map
}
Expand Down
33 changes: 23 additions & 10 deletions web/siteplan/src/service/SvgCatalogService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ import SignalSVGCatalog from '@/util/SVG/SVGCatalog/SignalSVGCatalog'
import TrackCloseSVGCatalog from '@/util/SVG/SVGCatalog/TrackCloseSVGCatalog'
import TrackLockSVGCatalog from '@/util/SVG/SVGCatalog/TrackLockSVGCatalog'
import { AndereSignalGroup, HauptVorSignalGroup, OtherSVGCatalog, SVGMast } from '@/util/SVG/SvgEnum'
import { AxiosStatic } from 'axios'
import axios from 'axios'

export default class SvgCatalogService {
private static INSTANCE = new SvgCatalogService()

private catalogLoaded: Promise<void>
private catalog: Map<string, ISvgElement[]> = new Map<string, ISvgElement[]>()
private axios: AxiosStatic
private signalSVGCatalog: SignalSVGCatalog[] = []
private fmaComponentCatalog: FMAComponentCatalog
private pzbCatalog: PZBCatalog
Expand All @@ -55,9 +57,8 @@ export default class SvgCatalogService {
private lockKeyCatalog: LockKeySVGCatalog
private othersCatalog: OthersSVGCatalog
private cantCatalog: CantSVGCatalog
constructor (axios: AxiosStatic) {
this.axios = axios
this.loadSvgCatalog()
private constructor () {
this.catalogLoaded = this.loadSvgCatalog()
this.registerSignalSVGCatalog()

this.fmaComponentCatalog = new FMAComponentCatalog(this.catalog)
Expand All @@ -72,6 +73,14 @@ export default class SvgCatalogService {
this.othersCatalog = new OthersSVGCatalog(this.catalog)
}

public static getInstance () {
return SvgCatalogService.INSTANCE
}

public async isReady (): Promise<void> {
await this.catalogLoaded
}

public getSignalSVGCatalog (): SignalSVGCatalog[] {
return this.signalSVGCatalog
}
Expand Down Expand Up @@ -116,20 +125,24 @@ export default class SvgCatalogService {
}
}

private loadSvgCatalog (): void {
private async loadSvgCatalog (): Promise<void> {
console.info('Start loading svg catalog...')
const listSignalSvgFile = Object.assign({}, HauptVorSignalGroup, AndereSignalGroup, SVGMast)
const promises: Promise<void>[] = []
for (const [, file] of Object.entries(listSignalSvgFile)) {
this.loadSvgFile(file)
promises.push(this.loadSvgFile(file))
}
const listOtherSvgFile = Object.assign({}, OtherSVGCatalog)
for (const [, file] of Object.entries(listOtherSvgFile)) {
this.loadSvgFile(file)
promises.push(this.loadSvgFile(file))
}
await Promise.all(promises)
console.info('Loading svg catalog finished.')
}

private loadSvgFile (file: string): void {
private loadSvgFile (file: string): Promise<void> {
const parser = new DOMParser()
this.axios.get(`/SvgKatalog/${file}.svg`).then(response => {
return axios.get(`/SvgKatalog/${file}.svg`).then(response => {
const domXML = parser.parseFromString(response.data, 'image/svg+xml')
const svgs = this.createSVGElements(domXML)
this.catalog.set(file, svgs)
Expand Down
Loading
Loading