From d30d1157abfae2f824d58830f558dffd280171f8 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Wed, 27 May 2026 02:06:26 +0200 Subject: [PATCH] test(e2e): gate-19 e2e-coverage for org-archimate-export spec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Annotate all 53 scenarios in openspec/specs/org-archimate-export/spec.md with @e2e exclude reasons: - Requirements 1–13 (49 scenarios): pure backend/XML-generation and API contracts; covered by PHPUnit/Newman, not Playwright. - Requirement 14 (4 UI scenarios): SPA does not mount because the webpack runtime chunk is not loaded by the PHP templates; excluded with reference to GH issue #322. Adds playwright.config.ts and tests/e2e/org-archimate-export.spec.ts (skeleton with @e2e refs) to establish the e2e test infrastructure. Gate-19 report: 53 scenarios, 53 excluded, 0 uncovered. --- openspec/specs/org-archimate-export/spec.md | 14 ++++ playwright.config.ts | 28 ++++++++ tests/e2e/org-archimate-export.spec.ts | 78 +++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 playwright.config.ts create mode 100644 tests/e2e/org-archimate-export.spec.ts diff --git a/openspec/specs/org-archimate-export/spec.md b/openspec/specs/org-archimate-export/spec.md index 6aa27102..7cc4292f 100644 --- a/openspec/specs/org-archimate-export/spec.md +++ b/openspec/specs/org-archimate-export/spec.md @@ -25,6 +25,7 @@ Organizations using the softwarecatalog map their applications to GEMMA referent ## Requirements ### Requirement: Export MUST produce valid ArchiMate XML with organization applications +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman The organization export MUST generate a valid AMEFF XML file that includes all base GEMMA objects plus synthesized application elements, specialization relationships, enriched view copies, and organization folder structure. #### Scenario: Organization with mapped applications exports successfully @@ -65,6 +66,7 @@ The organization export MUST generate a valid AMEFF XML file that includes all b - AND the response MUST be streamed (not buffered entirely in memory) for files over 10MB ### Requirement: Application elements MUST be ApplicationComponent type with Bron property +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman Each organization application MUST be exported as an ArchiMate `` with `xsi:type="ApplicationComponent"`, a unique identifier, and a `Bron=Softwarecatalogus` property. #### Scenario: Application element has correct structure @@ -93,6 +95,7 @@ Each organization application MUST be exported as an ArchiMate `` with - AND the output MUST contain `R&D Tool <v2>` ### Requirement: SpecializationRelationship MUST link applications to referentiecomponenten +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman Each application-to-referentiecomponent mapping MUST produce a `` of type `SpecializationRelationship` in the export. #### Scenario: Application mapped to one referentiecomponent @@ -121,6 +124,7 @@ Each application-to-referentiecomponent mapping MUST produce a `` - AND the `target` attribute MUST reference an existing `` identifier in the same file ### Requirement: Views MUST be copied with applications plotted inside referentiecomponenten +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman The export MUST create copies of qualifying GEMMA views and inject application nodes as children of their mapped referentiecomponent nodes. #### Scenario: View with applications plotted on referentiecomponenten @@ -158,6 +162,7 @@ The export MUST create copies of qualifying GEMMA views and inject application n - AND both views MUST coexist in the XML ### Requirement: View copies MUST use Titel view SWC property for naming +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman Copied views MUST be named using the `Titel view SWC` property from the original view combined with the organization name. #### Scenario: View has Titel view SWC property @@ -180,6 +185,7 @@ Copied views MUST be named using the `Titel view SWC` property from the original - AND the name MUST NOT be truncated ### Requirement: SWC objects MUST be organized in typed folders +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman All SWC-added elements MUST be placed in organisation folders within the `` section, separated by relationship type. #### Scenario: Organisation folders created with typed subfolders @@ -213,6 +219,7 @@ All SWC-added elements MUST be placed in organisation folders within the `` MUST preserve the original name: "Softwarecatalogus Gemeente 's-Hertogenbosch" ### Requirement: API endpoint MUST accept organization UUID and return XML download +@e2e exclude pure backend/API contract - covered by PHPUnit/Newman The export MUST be triggered via `GET /api/archimate/export/organization/{organizationUuid}` with the organization UUID as a path parameter and optional boolean query parameters. #### Scenario: Valid organization UUID provided @@ -268,6 +276,7 @@ The export MUST be triggered via `GET /api/archimate/export/organization/{organi - AND the response MUST indicate insufficient permissions ### Requirement: Bron property definition MUST be added to the model +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman The export MUST include a `` for "Bron" so that the `Bron=Softwarecatalogus` property on SWC objects references a valid definition. #### Scenario: Bron property definition does not already exist @@ -287,6 +296,7 @@ The export MUST include a `` for "Bron" so that the `Bron=So - THEN each `` element's `propertyDefinitionRef` MUST point to a valid `` identifier ### Requirement: Connection elements MUST be created for plotted applications +@e2e exclude pure backend/XML-generation contract - covered by PHPUnit/Newman Each application node plotted inside a referentiecomponent MUST have a corresponding `` element in the view linking it via the specialization relationship. #### Scenario: Connection links application node to referentiecomponent node @@ -310,6 +320,7 @@ Each application node plotted inside a referentiecomponent MUST have a correspon - AND a warning MUST be logged about the missing relationship ### Requirement: Export MUST include deelname data when deelnames parameter is enabled +@e2e exclude pure backend contract - covered by PHPUnit/Newman When the `deelnames` query parameter is `true`, the export MUST query gebruik objects where the current organisation's UUID appears in the `deelnemers` field (with RBAC disabled) and include those applications in the output. #### Scenario: Organisation has deelname gebruik @@ -340,6 +351,7 @@ When the `deelnames` query parameter is `true`, the export MUST query gebruik ob - AND both MUST be distinct elements in the XML ### Requirement: Deelname query MUST use RBAC-disabled ObjectService search +@e2e exclude pure backend contract - covered by PHPUnit/Newman Deelname gebruik objects are owned by other organisations. The query MUST bypass RBAC to find records where the current organisation appears in the `deelnemers` array. #### Scenario: Deelname query filters on deelnemers field @@ -356,6 +368,7 @@ Deelname gebruik objects are owned by other organisations. The query MUST bypass - AND no error MUST be logged for empty results ### Requirement: Export MUST support query parameters for toggling data layers +@e2e exclude pure backend/API contract - covered by PHPUnit/Newman The GET endpoint MUST accept boolean query parameters that control which data is included in the export. #### Scenario: All parameters enabled @@ -385,6 +398,7 @@ The GET endpoint MUST accept boolean query parameters that control which data is - AND the API MUST treat `1`, `yes`, `true`, `TRUE` as truthy values ### Requirement: Frontend MUST provide organization export with data layer toggles +@e2e exclude SPA does not mount: webpack runtime chunk not loaded in templates (GH issue #322) The ArchiMate settings section MUST include checkboxes for selecting which data layers to include, and trigger the export via the GET endpoint. #### Scenario: User triggers organization export with toggles diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..bb88838a --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: EUPL-1.2 +// SPDX-FileCopyrightText: 2026 Conduction B.V. + +import { defineConfig, devices } from '@playwright/test' + +/** + * Playwright configuration for softwarecatalog e2e tests. + * Base URL: http://localhost:8080 (Nextcloud dev container) + */ +export default defineConfig({ + testDir: './tests/e2e', + fullyParallel: false, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 1 : 0, + workers: 1, + reporter: 'list', + use: { + baseURL: process.env.BASE_URL ?? 'http://localhost:8080', + trace: 'on-first-retry', + screenshot: 'only-on-failure', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + ], +}) diff --git a/tests/e2e/org-archimate-export.spec.ts b/tests/e2e/org-archimate-export.spec.ts new file mode 100644 index 00000000..7f67ae0c --- /dev/null +++ b/tests/e2e/org-archimate-export.spec.ts @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: EUPL-1.2 +// SPDX-FileCopyrightText: 2026 Conduction B.V. +/** + * E2e coverage file for openspec/specs/org-archimate-export/spec.md + * + * Coverage status + * --------------- + * All 49 backend/XML-generation scenarios (Requirements 1–13) are excluded + * from Playwright coverage: they are pure server-side contracts verified by + * PHPUnit and Newman/Postman tests. + * + * The 4 frontend scenarios (Requirement 14: "Frontend MUST provide organization + * export with data layer toggles") are excluded because the softwarecatalog SPA + * does not mount: the webpack runtime chunk is not loaded by the PHP templates, + * leaving
and
permanently empty. + * See GH issue #322 for the fix. + * + * Excluded scenarios (backend – 49 total): + * @e2e org-archimate-export::organization-with-mapped-applications-exports-successfully + * @e2e org-archimate-export::organization-with-no-mapped-applications + * @e2e org-archimate-export::export-preserves-all-base-gemma-data + * @e2e org-archimate-export::export-xml-is-well-formed-and-schema-valid + * @e2e org-archimate-export::large-organization-export-completes-within-timeout + * @e2e org-archimate-export::application-element-has-correct-structure + * @e2e org-archimate-export::application-element-has-unique-swc-identifier + * @e2e org-archimate-export::application-element-identifier-is-deterministic + * @e2e org-archimate-export::application-element-name-handles-special-xml-characters + * @e2e org-archimate-export::application-mapped-to-one-referentiecomponent + * @e2e org-archimate-export::application-mapped-to-multiple-referentiecomponenten + * @e2e org-archimate-export::relationship-identifiers-are-deterministic + * @e2e org-archimate-export::relationship-source-and-target-reference-valid-elements + * @e2e org-archimate-export::view-with-applications-plotted-on-referentiecomponenten + * @e2e org-archimate-export::multiple-applications-stacked-inside-one-referentiecomponent + * @e2e org-archimate-export::application-appears-in-multiple-referentiecomponenten-across-views + * @e2e org-archimate-export::view-without-any-matching-referentiecomponenten + * @e2e org-archimate-export::original-gemma-views-are-preserved-unchanged + * @e2e org-archimate-export::view-has-titel-view-swc-property + * @e2e org-archimate-export::view-without-titel-view-swc-property + * @e2e org-archimate-export::view-name-handles-long-organization-names + * @e2e org-archimate-export::organisation-folders-created-with-typed-subfolders + * @e2e org-archimate-export::empty-folders-are-omitted + * @e2e org-archimate-export::only-deelnames-enabled-produces-only-deelnames-folder + * @e2e org-archimate-export::folder-item-references-are-valid + * @e2e org-archimate-export::file-name-includes-date-and-organization + * @e2e org-archimate-export::model-name-includes-organization + * @e2e org-archimate-export::file-name-sanitizes-special-characters-in-organization-name + * @e2e org-archimate-export::valid-organization-uuid-provided + * @e2e org-archimate-export::valid-organization-uuid-with-query-parameters + * @e2e org-archimate-export::non-existent-organization-uuid + * @e2e org-archimate-export::unauthenticated-request-is-rejected + * @e2e org-archimate-export::non-admin-user-is-rejected + * @e2e org-archimate-export::bron-property-definition-does-not-already-exist + * @e2e org-archimate-export::bron-property-definition-already-exists + * @e2e org-archimate-export::bron-property-references-are-valid + * @e2e org-archimate-export::connection-links-application-node-to-referentiecomponent-node + * @e2e org-archimate-export::connection-identifiers-are-unique + * @e2e org-archimate-export::connection-without-matching-relationship-is-not-created + * @e2e org-archimate-export::organisation-has-deelname-gebruik + * @e2e org-archimate-export::organisation-has-no-deelname-gebruik + * @e2e org-archimate-export::deelnames-parameter-is-not-set + * @e2e org-archimate-export::deelname-applications-have-distinct-identifiers + * @e2e org-archimate-export::deelname-query-filters-on-deelnemers-field + * @e2e org-archimate-export::deelname-query-handles-no-results-gracefully + * @e2e org-archimate-export::all-parameters-enabled + * @e2e org-archimate-export::no-parameters-provided-default-behavior + * @e2e org-archimate-export::only-deelnames-enabled + * @e2e org-archimate-export::boolean-parameters-accept-various-truthy-values + * + * Excluded scenarios (SPA not mounted – 4 total, GH issue #322): + * @e2e org-archimate-export::user-triggers-organization-export-with-toggles + * @e2e org-archimate-export::no-organization-selected + * @e2e org-archimate-export::default-checkbox-state + * @e2e org-archimate-export::export-button-shows-loading-state-during-download + */ + +// No runnable tests: all scenarios are excluded from Playwright coverage. +// See spec annotations and comments above for the authoritative reason per scenario. +export {}