@forsakringskassan/cypress-config 0.0.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,45 +1,78 @@
1
- # @forsakringskassan/cypress-config
1
+ # `@forsakringskassan/cypress-config`
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ Sharable Cypress configuration building blocks for Försäkringskassan.
4
4
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
5
+ ## Usage
6
6
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
7
+ In `cypress.config.ts`, replace the vanilla `defineConfig()` helper from `cypress` with `@forsakringskassan/cypress-config`:
8
8
 
9
- ## Purpose
9
+ ```diff
10
+ -import { defineConfig } from "cypress";
11
+ +import { defineConfig } from "@forsakringskassan/cypress-config";
10
12
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@forsakringskassan/cypress-config`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
13
+ export default defineConfig({
14
+ /* ... */
15
+ });
16
+ ```
15
17
 
16
- ## What is OIDC Trusted Publishing?
18
+ It works the same but is preconfigured with new defaults.
17
19
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
20
+ > [!TIP]
21
+ > The `defineConfig()` helper does not require any parameters.
22
+ > Unless you are explicitly overwriting the default configuration it is recommended to call `defineConfig()` without parameters.
23
+ >
24
+ > ```ts
25
+ > export default defineConfig();
26
+ > ```
27
+ >
28
+ > This ensures maximum compatibility with future releases.
19
29
 
20
- ## Setup Instructions
30
+ A configuration function is available for usage in `cypress/support/e2e.ts` and/or `cypress/support/component.ts`:
21
31
 
22
- To properly configure OIDC trusted publishing for this package:
32
+ ```ts
33
+ import { configure } from "@forsakringskassan/cypress-config/support";
23
34
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
35
+ configure({
36
+ afterEach: {
37
+ htmlvalidate: true,
38
+ },
39
+ });
40
+ ```
28
41
 
29
- ## DO NOT USE THIS PACKAGE
42
+ > [!NOTE]
43
+ > The `configure()` function is expected to be called exactly once.
44
+ > If the call is omitted some functionality will not work as expected.
45
+ > Calling it multiple times is undefined behaviour.
30
46
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
47
+ See the various components for details.
36
48
 
37
- ## More Information
49
+ ### HTML-Validate
38
50
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
51
+ A preconfigured [HTML-validate](https://html-validate.org/) plugin ([cypress-html-validate](https://gitlab.com/html-validate/cypress-html-validate/)) is exported as `htmlValidatePlugin`:
42
52
 
43
- ---
53
+ ```ts
54
+ import {
55
+ defineConfig,
56
+ htmlValidatePlugin,
57
+ } from "@forsakringskassan/cypress-config";
44
58
 
45
- **Maintained for OIDC setup purposes only**
59
+ export default defineConfig({
60
+ component: {
61
+ async setupNodeEvents(on, config) {
62
+ config = await htmlValidatePlugin(on, config);
63
+ },
64
+ },
65
+ });
66
+ ```
67
+
68
+ To automatically run validation after each test configure it using the configuration function:
69
+
70
+ ```ts
71
+ import { configure } from "@forsakringskassan/cypress-config/support";
72
+
73
+ configure({
74
+ afterEach: {
75
+ htmlvalidate: true,
76
+ },
77
+ });
78
+ ```
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width,initial-scale=1.0" />
7
+ <title>Components App</title>
8
+ </head>
9
+ <body>
10
+ <div data-cy-root>
11
+ <div id="teleport"></div>
12
+ </div>
13
+ </body>
14
+ </html>
@@ -0,0 +1,49 @@
1
+ import { ConfigData } from 'cypress-html-validate';
2
+ import { CypressHtmlValidateOptions } from 'cypress-html-validate';
3
+ import { defineConfig as defineConfig_2 } from 'cypress';
4
+
5
+ /**
6
+ * @public
7
+ */
8
+ export declare type ConfigOptions = Parameters<typeof defineConfig_2>[0];
9
+
10
+ /**
11
+ * Default cypress configuration.
12
+ *
13
+ * @public
14
+ * @since v1.0.0
15
+ */
16
+ export declare const defaultConfig: Readonly<{
17
+ allowCypressEnv: false;
18
+ video: false;
19
+ component: {
20
+ devServer: {
21
+ framework: "vue";
22
+ bundler: "vite";
23
+ };
24
+ indexHtmlFile: string;
25
+ };
26
+ }>;
27
+
28
+ /**
29
+ * @public
30
+ * @since v1.0.0
31
+ */
32
+ export declare function defineConfig(userConfig?: Omit<ConfigOptions, "component"> & {
33
+ component?: Partial<ConfigOptions["component"]>;
34
+ }): Readonly<ConfigOptions>;
35
+
36
+ /**
37
+ * Preconfigured `cypress-html-validate` plugin.
38
+ *
39
+ * @public
40
+ * @since v1.0.0
41
+ * @param on - Cypress `on` callback from `setupNodeEvents`.
42
+ * @param cypressConfig - Cypress `config` parameter from `setupNodeEvents`.
43
+ * @param userConfig - Custom configuration to pass to `html-validate`.
44
+ * @param userOptions - Custom options to pass to `cypress-html-validate`.
45
+ * @returns A promise resolved with the updated cypress configuration.
46
+ */
47
+ export declare function htmlValidatePlugin(on: Cypress.PluginEvents, cypressConfig: Cypress.PluginConfigOptions, userConfig?: ConfigData, userOptions?: CypressHtmlValidateOptions): Promise<Cypress.PluginConfigOptions>;
48
+
49
+ export { }
package/dist/index.mjs ADDED
@@ -0,0 +1,225 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ try {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ } catch (e) {
11
+ throw mod = 0, e;
12
+ }
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+
31
+ // node_modules/deepmerge/dist/cjs.js
32
+ var require_cjs = __commonJS({
33
+ "node_modules/deepmerge/dist/cjs.js"(exports, module) {
34
+ "use strict";
35
+ var isMergeableObject = function isMergeableObject2(value) {
36
+ return isNonNullObject(value) && !isSpecial(value);
37
+ };
38
+ function isNonNullObject(value) {
39
+ return !!value && typeof value === "object";
40
+ }
41
+ function isSpecial(value) {
42
+ var stringValue = Object.prototype.toString.call(value);
43
+ return stringValue === "[object RegExp]" || stringValue === "[object Date]" || isReactElement(value);
44
+ }
45
+ var canUseSymbol = typeof Symbol === "function" && Symbol.for;
46
+ var REACT_ELEMENT_TYPE = canUseSymbol ? /* @__PURE__ */ Symbol.for("react.element") : 60103;
47
+ function isReactElement(value) {
48
+ return value.$$typeof === REACT_ELEMENT_TYPE;
49
+ }
50
+ function emptyTarget(val) {
51
+ return Array.isArray(val) ? [] : {};
52
+ }
53
+ function cloneUnlessOtherwiseSpecified(value, options) {
54
+ return options.clone !== false && options.isMergeableObject(value) ? deepmerge2(emptyTarget(value), value, options) : value;
55
+ }
56
+ function defaultArrayMerge(target, source, options) {
57
+ return target.concat(source).map(function(element) {
58
+ return cloneUnlessOtherwiseSpecified(element, options);
59
+ });
60
+ }
61
+ function getMergeFunction(key, options) {
62
+ if (!options.customMerge) {
63
+ return deepmerge2;
64
+ }
65
+ var customMerge = options.customMerge(key);
66
+ return typeof customMerge === "function" ? customMerge : deepmerge2;
67
+ }
68
+ function getEnumerableOwnPropertySymbols(target) {
69
+ return Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
70
+ return Object.propertyIsEnumerable.call(target, symbol);
71
+ }) : [];
72
+ }
73
+ function getKeys(target) {
74
+ return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target));
75
+ }
76
+ function propertyIsOnObject(object, property) {
77
+ try {
78
+ return property in object;
79
+ } catch (_) {
80
+ return false;
81
+ }
82
+ }
83
+ function propertyIsUnsafe(target, key) {
84
+ return propertyIsOnObject(target, key) && !(Object.hasOwnProperty.call(target, key) && Object.propertyIsEnumerable.call(target, key));
85
+ }
86
+ function mergeObject(target, source, options) {
87
+ var destination = {};
88
+ if (options.isMergeableObject(target)) {
89
+ getKeys(target).forEach(function(key) {
90
+ destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
91
+ });
92
+ }
93
+ getKeys(source).forEach(function(key) {
94
+ if (propertyIsUnsafe(target, key)) {
95
+ return;
96
+ }
97
+ if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
98
+ destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
99
+ } else {
100
+ destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
101
+ }
102
+ });
103
+ return destination;
104
+ }
105
+ function deepmerge2(target, source, options) {
106
+ options = options || {};
107
+ options.arrayMerge = options.arrayMerge || defaultArrayMerge;
108
+ options.isMergeableObject = options.isMergeableObject || isMergeableObject;
109
+ options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
110
+ var sourceIsArray = Array.isArray(source);
111
+ var targetIsArray = Array.isArray(target);
112
+ var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
113
+ if (!sourceAndTargetTypesMatch) {
114
+ return cloneUnlessOtherwiseSpecified(source, options);
115
+ } else if (sourceIsArray) {
116
+ return options.arrayMerge(target, source, options);
117
+ } else {
118
+ return mergeObject(target, source, options);
119
+ }
120
+ }
121
+ deepmerge2.all = function deepmergeAll(array, options) {
122
+ if (!Array.isArray(array)) {
123
+ throw new Error("first argument should be an array");
124
+ }
125
+ return array.reduce(function(prev, next) {
126
+ return deepmerge2(prev, next, options);
127
+ }, {});
128
+ };
129
+ var deepmerge_1 = deepmerge2;
130
+ module.exports = deepmerge_1;
131
+ }
132
+ });
133
+
134
+ // src/plugins/html-validate.ts
135
+ import { createRequire } from "node:module";
136
+ import "cypress";
137
+ import { install } from "cypress-html-validate/plugin";
138
+
139
+ // src/utils/merge-config.ts
140
+ var import_deepmerge = __toESM(require_cjs(), 1);
141
+ function overwriteMerge(_a, b) {
142
+ return b;
143
+ }
144
+ function mergeConfig(a, b) {
145
+ return (0, import_deepmerge.default)(a, b ?? {}, { arrayMerge: overwriteMerge });
146
+ }
147
+
148
+ // src/plugins/html-validate.ts
149
+ var require2 = createRequire(import.meta.url);
150
+ var exclude = [];
151
+ try {
152
+ exclude = require2("@fkui/vue/htmlvalidate/cypress");
153
+ } catch {
154
+ }
155
+ var htmlValidateConfig = () => {
156
+ return {
157
+ rules: {
158
+ /* some examples show how to use custom heading levels which often
159
+ * doesn't match the heading outline for the documentation */
160
+ "heading-level": ["off"],
161
+ /* prevents mismatches from disabled rules which does not trigger errors
162
+ * when Cypress tests are running but would yield errors during normal
163
+ * validation */
164
+ "no-unused-disable": "off",
165
+ /* we cannot use native progressbar element due to SLA */
166
+ "prefer-native-element": [
167
+ "error",
168
+ {
169
+ exclude: ["progressbar"]
170
+ }
171
+ ],
172
+ /* sadly we dont use SRI at FK */
173
+ "require-sri": "off"
174
+ }
175
+ };
176
+ };
177
+ var htmlValidateOptions = () => {
178
+ return {
179
+ include: [
180
+ /* Cypress component tests */
181
+ "#__cy_vue_root > div",
182
+ /* @forsakringskassan/docs-generator examples */
183
+ ".code-preview__preview",
184
+ /* @forsakringskassan/docs-live-example examples */
185
+ ".live-example__example"
186
+ ],
187
+ exclude
188
+ };
189
+ };
190
+ function htmlValidatePlugin(on, cypressConfig, userConfig, userOptions) {
191
+ const config = mergeConfig(htmlValidateConfig(), userConfig);
192
+ const options = mergeConfig(htmlValidateOptions(), userOptions);
193
+ install(on, config, options);
194
+ return Promise.resolve(cypressConfig);
195
+ }
196
+
197
+ // src/default-config.ts
198
+ import { createRequire as createRequire2 } from "node:module";
199
+ var require3 = createRequire2(import.meta.url);
200
+ var defaultConfig = Object.freeze({
201
+ allowCypressEnv: false,
202
+ /* disable video recording, it is to slow both on remote machines and on
203
+ * CI/CD testing. */
204
+ video: false,
205
+ component: {
206
+ devServer: {
207
+ framework: "vue",
208
+ bundler: "vite"
209
+ },
210
+ indexHtmlFile: require3.resolve("#assets/component-index.html")
211
+ }
212
+ });
213
+
214
+ // src/define-config.ts
215
+ function defineConfig(userConfig) {
216
+ return mergeConfig(
217
+ defaultConfig,
218
+ userConfig
219
+ );
220
+ }
221
+ export {
222
+ defaultConfig,
223
+ defineConfig,
224
+ htmlValidatePlugin
225
+ };
@@ -0,0 +1,15 @@
1
+ import "cypress-html-validate/commands";
2
+
3
+ /**
4
+ * Configure plugins.
5
+ *
6
+ * @public
7
+ * @since v1.0.0
8
+ */
9
+ export declare function configure(options: {
10
+ afterEach: {
11
+ htmlvalidate: boolean;
12
+ };
13
+ }): void;
14
+
15
+ export { }
@@ -0,0 +1,15 @@
1
+ // src/support/html-validate.ts
2
+ import "cypress-html-validate/commands";
3
+
4
+ // src/support/configure.ts
5
+ import "cypress";
6
+ function configure(options) {
7
+ if (options.afterEach.htmlvalidate) {
8
+ afterEach(() => {
9
+ cy.htmlvalidate();
10
+ });
11
+ }
12
+ }
13
+ export {
14
+ configure
15
+ };
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.59.0"
9
+ }
10
+ ]
11
+ }
package/package.json CHANGED
@@ -1,10 +1,53 @@
1
1
  {
2
2
  "name": "@forsakringskassan/cypress-config",
3
- "version": "0.0.0",
4
- "description": "OIDC trusted publishing setup package for @forsakringskassan/cypress-config",
3
+ "version": "1.0.0",
4
+ "description": "Sharable Cypress configuration building blocks for Försäkringskassan",
5
5
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
6
+ "cypress"
7
+ ],
8
+ "homepage": "https://github.com/Forsakringskassan/cypress-config#readme",
9
+ "bugs": {
10
+ "url": "https://github.com/Forsakringskassan/cypress-config/issues"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/Forsakringskassan/cypress-config.git"
15
+ },
16
+ "license": "MIT",
17
+ "author": "Försäkringskassan",
18
+ "sideEffects": [
19
+ "./dist/support.mjs",
20
+ "./src/support/html-validate.ts"
21
+ ],
22
+ "type": "module",
23
+ "imports": {
24
+ "#assets/*": "./assets/*"
25
+ },
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "default": "./dist/index.mjs"
30
+ },
31
+ "./support": {
32
+ "types": "./dist/support.d.ts",
33
+ "default": "./dist/support.mjs"
34
+ }
35
+ },
36
+ "main": "dist/index.mjs",
37
+ "files": [
38
+ "assets",
39
+ "dist"
40
+ ],
41
+ "dependencies": {
42
+ "cypress-html-validate": "9.0.0"
43
+ },
44
+ "peerDependencies": {
45
+ "@fkui/vue": ">= 6.0.0",
46
+ "cypress": "^15.0.0",
47
+ "html-validate": ">= 8.0.0"
48
+ },
49
+ "engines": {
50
+ "node": "^22.16 || >= 24",
51
+ "npm": ">= 7"
52
+ }
10
53
  }