@trackunit/iris-app-e2e 1.8.86 → 1.8.88-alpha-c57027e60fa.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
@@ -53,7 +53,8 @@ npm install cypress @testing-library/cypress --save-dev
53
53
  Create a `cypress/support/e2e.ts` file:
54
54
 
55
55
  ```typescript
56
- import { setupDefaultCommands, setupE2E } from '@trackunit/iris-app-e2e';
56
+ // Import browser-only utilities from /support (NOT the base path)
57
+ import { setupDefaultCommands, setupE2E } from '@trackunit/iris-app-e2e/support';
57
58
 
58
59
  // Set up E2E environment
59
60
  setupE2E();
@@ -0,0 +1 @@
1
+ exports._default = require('./index.cjs.js').default;
package/index.cjs.js CHANGED
@@ -4,6 +4,8 @@ var fs = require('fs');
4
4
  var path = require('path');
5
5
  var crypto = require('crypto');
6
6
  var nodeXlsx = require('node-xlsx');
7
+ var cypressPreset = require('@nx/cypress/plugins/cypress-preset');
8
+ var nxTsconfigPaths_plugin = require('@nx/vite/plugins/nx-tsconfig-paths.plugin');
7
9
 
8
10
  function _interopNamespaceDefault(e) {
9
11
  var n = Object.create(null);
@@ -24,138 +26,6 @@ function _interopNamespaceDefault(e) {
24
26
 
25
27
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
26
28
 
27
- /**
28
- * Sets up default Cypress commands for E2E testing.
29
- * Adds custom commands like getByTestId, login, enterIrisApp, etc.
30
- */
31
- function setupDefaultCommands() {
32
- Cypress.Commands.add("getByTestId", {
33
- prevSubject: ["optional"],
34
- },
35
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
- (subject, testId, options = {}) => {
37
- const selector = `[data-testid="${testId}"]`;
38
- const timeout = options.timeout ?? 15000;
39
- if (subject) {
40
- if (Cypress.dom.isElement(subject) || Cypress.dom.isJquery(subject)) {
41
- return cy.wrap(subject, { timeout }).find(selector, { timeout });
42
- }
43
- else if (Cypress.dom.isWindow(subject)) {
44
- return cy.get(selector, { timeout });
45
- }
46
- else if (Array.isArray(subject)) {
47
- const element = subject.map(el => cy.wrap(el, { timeout }).find(selector, { timeout }));
48
- if (element[0]) {
49
- return element[0];
50
- }
51
- return cy.wrap(null);
52
- }
53
- return cy.get(selector, { timeout });
54
- }
55
- else {
56
- return cy.get(selector, { timeout });
57
- }
58
- });
59
- Cypress.Commands.add("login", fixture => {
60
- const envUrl = `${Cypress.config().baseUrl}/env`;
61
- cy.log(`Getting env from: ${envUrl}`);
62
- cy.request({
63
- method: "GET",
64
- url: envUrl,
65
- headers: {
66
- "Content-Type": "application/json",
67
- },
68
- }).then(envResponse => {
69
- const env = envResponse.body;
70
- const domain = env.auth?.url;
71
- if (!(Boolean(domain))) {
72
- throw new Error(`No domain found from servers /env found env: ${JSON.stringify(env)}`);
73
- }
74
- cy.log(`Using: ${domain}`);
75
- cy.clearCookies();
76
- cy.fixture(fixture ?? "auth").then(({ username, password }) => {
77
- const options = {
78
- warnBeforePasswordExpired: true,
79
- multiOptionalFactorEnroll: false,
80
- };
81
- cy.request({
82
- method: "POST",
83
- url: `${domain}/api/v1/authn`,
84
- headers: {
85
- "Content-Type": "application/json",
86
- },
87
- body: {
88
- username,
89
- password,
90
- options,
91
- },
92
- })
93
- .then(response => {
94
- if (response.isOkStatusCode) {
95
- const sessionToken = response.body.sessionToken;
96
- return cy.visit(`/auth/manager-classic#session_token=${sessionToken}&fleetHome=true`);
97
- }
98
- else {
99
- throw new Error(`Could not get a session token for user: ${username}, ${JSON.stringify(response)}`);
100
- }
101
- })
102
- .then(() => cy.url({ timeout: 20000 }).should("not.include", "manager-classic")) // Wait for redirect away from manager-classic
103
- .url()
104
- .should("contain", `${Cypress.config().baseUrl}`);
105
- cy.get("#host-layout-content", { timeout: 15000 }).should("be.visible"); // Wait for host layout to be visible
106
- });
107
- });
108
- });
109
- Cypress.Commands.add("switchToLocalDevMode", () => {
110
- cy.getByTestId("developerPortalNav").click();
111
- cy.url({ timeout: 15000, log: true }).should("contain", "/iris-sdk-portal");
112
- //eslint-disable-next-line @typescript-eslint/no-explicit-any
113
- cy.getByTestId("localDevModeSwitch-input").then(($ele) => {
114
- if ($ele && !$ele.is(":checked")) {
115
- cy.getByTestId("localDevModeSwitch-thumb").click();
116
- }
117
- });
118
- });
119
- Cypress.Commands.add("enterIrisApp", options => {
120
- return cy
121
- .get(`iframe[data-testid="${options?.testId ?? "app-iframe"}"]`, { timeout: 30000 })
122
- .first()
123
- .its("0.contentDocument.body", { timeout: 30000, log: true })
124
- .should("not.be.empty")
125
- .then($body => {
126
- return () => cy.wrap($body);
127
- });
128
- });
129
- Cypress.Commands.add("enterStorybookPreview", options => {
130
- return cy
131
- .get(`iframe[id="${options?.testId ?? "storybook-preview-iframe"}"]`, { timeout: 30000 })
132
- .first()
133
- .its("0.contentDocument.body", { timeout: 30000, log: true })
134
- .should("not.be.empty")
135
- .then($body => {
136
- return () => cy.wrap($body);
137
- });
138
- });
139
- Cypress.Commands.add("getValidateFeatureFlags", () => {
140
- cy.intercept({ url: "**/ValidateFeatureFlags" }).as("ValidateFeatureFlags");
141
- cy.intercept({ url: "**/UserPermissions" }).as("UserPermissions");
142
- cy.intercept({ url: "**/ActiveSubscription" }).as("ActiveSubscription");
143
- });
144
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
145
- let ccData = null;
146
- Cypress.Commands.add("configCat", value => {
147
- if (!ccData) {
148
- cy.wait("@ValidateFeatureFlags").then(intercept => {
149
- ccData = intercept.response?.body?.data?.featureFlags;
150
- return ccData?.find((ff) => ff.key === value).state;
151
- });
152
- }
153
- else {
154
- return ccData?.find((ff) => ff.key === value).state;
155
- }
156
- });
157
- }
158
-
159
29
  /* eslint-disable no-console */
160
30
  /**
161
31
  * Writes a file with Prettier formatting applied.
@@ -376,7 +246,7 @@ function sanitizeForFilename(str) {
376
246
  * // Returns: "Test with - special chars (passed) (attempt 3)"
377
247
  */
378
248
  function fileNameBuilder(testName, state, currentRetry) {
379
- const fileName = `${testName} ${currentRetry !== undefined ? `(Attempt ${currentRetry + 1})` : ""} (${state.toLowerCase()})`;
249
+ const fileName = `${testName} ${""} (${state.toLowerCase()})`;
380
250
  return sanitizeForFilename(fileName);
381
251
  }
382
252
 
@@ -509,71 +379,44 @@ const setupPlugins = (on, config, logWriter, installHarGenerator) => {
509
379
  return config;
510
380
  };
511
381
 
512
- /* eslint-disable @typescript-eslint/no-explicit-any */
513
382
  /**
514
- * Sets up HAR (HTTP Archive) recording for E2E tests.
515
- * Records network activity and saves HAR files for failed tests.
516
- */
517
- function setupHarRecording() {
518
- // eslint-disable-next-line @typescript-eslint/no-require-imports
519
- require("@neuralegion/cypress-har-generator/commands");
520
- beforeEach(() => {
521
- const harDir = Cypress.env("hars_folders");
522
- cy.recordHar({ rootDir: harDir });
523
- });
524
- afterEach(function () {
525
- if (this.currentTest.state === "failed") {
526
- const harDir = Cypress.env("hars_folders");
527
- const testName = fileNameBuilder(`${Cypress.currentTest.titlePath[0]} - ${Cypress.currentTest.title}`, "failed", Cypress.currentRetry);
528
- cy.saveHar({ outDir: harDir, fileName: testName });
529
- }
530
- });
531
- }
532
-
533
- /**
534
- * Sets up the E2E testing environment with HAR recording and terminal logging.
383
+ * Creates the standard NX E2E preset configuration for Cypress.
384
+ * This wraps the @nx/cypress preset with our default Vite configuration.
385
+ *
386
+ * @param filename - Pass `__filename` from the calling cypress.config.ts
387
+ * @example
388
+ * ```ts
389
+ * import { createNxPreset, CypressPluginConfig, defaultCypressConfig, setupPlugins } from "@trackunit/iris-app-e2e";
390
+ * import { defineConfig } from "cypress";
391
+ *
392
+ * const nxPreset = createNxPreset(__filename);
393
+ *
394
+ * export default defineConfig({
395
+ * chromeWebSecurity: false,
396
+ * e2e: {
397
+ * ...nxPreset,
398
+ * ...defaultCypressConfig(__dirname),
399
+ * async setupNodeEvents(on, config: CypressPluginConfig) {
400
+ * await nxPreset.setupNodeEvents?.(on, config);
401
+ * return setupPlugins(on, config, formatter, installHarGenerator);
402
+ * },
403
+ * },
404
+ * });
405
+ * ```
535
406
  */
536
- function setupE2E() {
537
- setupHarRecording();
538
- // eslint-disable-next-line @typescript-eslint/no-require-imports
539
- require("cypress-terminal-report/src/installLogsCollector")({
540
- xhr: {
541
- printHeaderData: true,
542
- printRequestData: true,
407
+ function createNxPreset(filename) {
408
+ return cypressPreset.nxE2EPreset(filename, {
409
+ bundler: "vite",
410
+ cypressDir: "cypress",
411
+ viteConfigOverrides: {
412
+ configFile: false,
413
+ plugins: [nxTsconfigPaths_plugin.nxViteTsPaths()],
543
414
  },
544
415
  });
545
- Cypress.on("uncaught:exception", (err) => {
546
- // eslint-disable-next-line no-console
547
- console.log("Caught Error: ", err);
548
- // returning false here prevents Cypress from
549
- // failing the test
550
- return false;
551
- });
552
- }
553
- const originalDescribe = global.describe;
554
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
555
- if (originalDescribe) {
556
- const codeowner = Cypress.env("codeowner");
557
- const addOwnerToTitle = (title) => {
558
- return codeowner ? title + ` [${codeowner}]` : title;
559
- };
560
- function patchedDescribe(title, fn) {
561
- return originalDescribe(addOwnerToTitle(title), fn);
562
- }
563
- patchedDescribe.only = (title, fn) => {
564
- return originalDescribe.only(addOwnerToTitle(title), fn);
565
- };
566
- patchedDescribe.skip = (title, fn) => {
567
- return originalDescribe.skip(addOwnerToTitle(title), fn);
568
- };
569
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
570
- global.describe = patchedDescribe;
571
416
  }
572
417
 
573
418
  exports.createLogFile = createLogFile;
419
+ exports.createNxPreset = createNxPreset;
574
420
  exports.defaultCypressConfig = defaultCypressConfig;
575
- exports.setupDefaultCommands = setupDefaultCommands;
576
- exports.setupE2E = setupE2E;
577
- exports.setupHarRecording = setupHarRecording;
578
421
  exports.setupPlugins = setupPlugins;
579
422
  exports.writeFileWithPrettier = writeFileWithPrettier;
package/index.cjs.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export * from './index.cjs.js';
2
+ export { _default as default } from './index.cjs.default.js';
package/index.esm.js CHANGED
@@ -3,138 +3,8 @@ import * as path from 'path';
3
3
  import path__default from 'path';
4
4
  import crypto from 'crypto';
5
5
  import { parse } from 'node-xlsx';
6
-
7
- /**
8
- * Sets up default Cypress commands for E2E testing.
9
- * Adds custom commands like getByTestId, login, enterIrisApp, etc.
10
- */
11
- function setupDefaultCommands() {
12
- Cypress.Commands.add("getByTestId", {
13
- prevSubject: ["optional"],
14
- },
15
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
- (subject, testId, options = {}) => {
17
- const selector = `[data-testid="${testId}"]`;
18
- const timeout = options.timeout ?? 15000;
19
- if (subject) {
20
- if (Cypress.dom.isElement(subject) || Cypress.dom.isJquery(subject)) {
21
- return cy.wrap(subject, { timeout }).find(selector, { timeout });
22
- }
23
- else if (Cypress.dom.isWindow(subject)) {
24
- return cy.get(selector, { timeout });
25
- }
26
- else if (Array.isArray(subject)) {
27
- const element = subject.map(el => cy.wrap(el, { timeout }).find(selector, { timeout }));
28
- if (element[0]) {
29
- return element[0];
30
- }
31
- return cy.wrap(null);
32
- }
33
- return cy.get(selector, { timeout });
34
- }
35
- else {
36
- return cy.get(selector, { timeout });
37
- }
38
- });
39
- Cypress.Commands.add("login", fixture => {
40
- const envUrl = `${Cypress.config().baseUrl}/env`;
41
- cy.log(`Getting env from: ${envUrl}`);
42
- cy.request({
43
- method: "GET",
44
- url: envUrl,
45
- headers: {
46
- "Content-Type": "application/json",
47
- },
48
- }).then(envResponse => {
49
- const env = envResponse.body;
50
- const domain = env.auth?.url;
51
- if (!(Boolean(domain))) {
52
- throw new Error(`No domain found from servers /env found env: ${JSON.stringify(env)}`);
53
- }
54
- cy.log(`Using: ${domain}`);
55
- cy.clearCookies();
56
- cy.fixture(fixture ?? "auth").then(({ username, password }) => {
57
- const options = {
58
- warnBeforePasswordExpired: true,
59
- multiOptionalFactorEnroll: false,
60
- };
61
- cy.request({
62
- method: "POST",
63
- url: `${domain}/api/v1/authn`,
64
- headers: {
65
- "Content-Type": "application/json",
66
- },
67
- body: {
68
- username,
69
- password,
70
- options,
71
- },
72
- })
73
- .then(response => {
74
- if (response.isOkStatusCode) {
75
- const sessionToken = response.body.sessionToken;
76
- return cy.visit(`/auth/manager-classic#session_token=${sessionToken}&fleetHome=true`);
77
- }
78
- else {
79
- throw new Error(`Could not get a session token for user: ${username}, ${JSON.stringify(response)}`);
80
- }
81
- })
82
- .then(() => cy.url({ timeout: 20000 }).should("not.include", "manager-classic")) // Wait for redirect away from manager-classic
83
- .url()
84
- .should("contain", `${Cypress.config().baseUrl}`);
85
- cy.get("#host-layout-content", { timeout: 15000 }).should("be.visible"); // Wait for host layout to be visible
86
- });
87
- });
88
- });
89
- Cypress.Commands.add("switchToLocalDevMode", () => {
90
- cy.getByTestId("developerPortalNav").click();
91
- cy.url({ timeout: 15000, log: true }).should("contain", "/iris-sdk-portal");
92
- //eslint-disable-next-line @typescript-eslint/no-explicit-any
93
- cy.getByTestId("localDevModeSwitch-input").then(($ele) => {
94
- if ($ele && !$ele.is(":checked")) {
95
- cy.getByTestId("localDevModeSwitch-thumb").click();
96
- }
97
- });
98
- });
99
- Cypress.Commands.add("enterIrisApp", options => {
100
- return cy
101
- .get(`iframe[data-testid="${options?.testId ?? "app-iframe"}"]`, { timeout: 30000 })
102
- .first()
103
- .its("0.contentDocument.body", { timeout: 30000, log: true })
104
- .should("not.be.empty")
105
- .then($body => {
106
- return () => cy.wrap($body);
107
- });
108
- });
109
- Cypress.Commands.add("enterStorybookPreview", options => {
110
- return cy
111
- .get(`iframe[id="${options?.testId ?? "storybook-preview-iframe"}"]`, { timeout: 30000 })
112
- .first()
113
- .its("0.contentDocument.body", { timeout: 30000, log: true })
114
- .should("not.be.empty")
115
- .then($body => {
116
- return () => cy.wrap($body);
117
- });
118
- });
119
- Cypress.Commands.add("getValidateFeatureFlags", () => {
120
- cy.intercept({ url: "**/ValidateFeatureFlags" }).as("ValidateFeatureFlags");
121
- cy.intercept({ url: "**/UserPermissions" }).as("UserPermissions");
122
- cy.intercept({ url: "**/ActiveSubscription" }).as("ActiveSubscription");
123
- });
124
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
- let ccData = null;
126
- Cypress.Commands.add("configCat", value => {
127
- if (!ccData) {
128
- cy.wait("@ValidateFeatureFlags").then(intercept => {
129
- ccData = intercept.response?.body?.data?.featureFlags;
130
- return ccData?.find((ff) => ff.key === value).state;
131
- });
132
- }
133
- else {
134
- return ccData?.find((ff) => ff.key === value).state;
135
- }
136
- });
137
- }
6
+ import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
7
+ import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
138
8
 
139
9
  /* eslint-disable no-console */
140
10
  /**
@@ -356,7 +226,7 @@ function sanitizeForFilename(str) {
356
226
  * // Returns: "Test with - special chars (passed) (attempt 3)"
357
227
  */
358
228
  function fileNameBuilder(testName, state, currentRetry) {
359
- const fileName = `${testName} ${currentRetry !== undefined ? `(Attempt ${currentRetry + 1})` : ""} (${state.toLowerCase()})`;
229
+ const fileName = `${testName} ${""} (${state.toLowerCase()})`;
360
230
  return sanitizeForFilename(fileName);
361
231
  }
362
232
 
@@ -489,65 +359,40 @@ const setupPlugins = (on, config, logWriter, installHarGenerator) => {
489
359
  return config;
490
360
  };
491
361
 
492
- /* eslint-disable @typescript-eslint/no-explicit-any */
493
362
  /**
494
- * Sets up HAR (HTTP Archive) recording for E2E tests.
495
- * Records network activity and saves HAR files for failed tests.
496
- */
497
- function setupHarRecording() {
498
- // eslint-disable-next-line @typescript-eslint/no-require-imports
499
- require("@neuralegion/cypress-har-generator/commands");
500
- beforeEach(() => {
501
- const harDir = Cypress.env("hars_folders");
502
- cy.recordHar({ rootDir: harDir });
503
- });
504
- afterEach(function () {
505
- if (this.currentTest.state === "failed") {
506
- const harDir = Cypress.env("hars_folders");
507
- const testName = fileNameBuilder(`${Cypress.currentTest.titlePath[0]} - ${Cypress.currentTest.title}`, "failed", Cypress.currentRetry);
508
- cy.saveHar({ outDir: harDir, fileName: testName });
509
- }
510
- });
511
- }
512
-
513
- /**
514
- * Sets up the E2E testing environment with HAR recording and terminal logging.
363
+ * Creates the standard NX E2E preset configuration for Cypress.
364
+ * This wraps the @nx/cypress preset with our default Vite configuration.
365
+ *
366
+ * @param filename - Pass `__filename` from the calling cypress.config.ts
367
+ * @example
368
+ * ```ts
369
+ * import { createNxPreset, CypressPluginConfig, defaultCypressConfig, setupPlugins } from "@trackunit/iris-app-e2e";
370
+ * import { defineConfig } from "cypress";
371
+ *
372
+ * const nxPreset = createNxPreset(__filename);
373
+ *
374
+ * export default defineConfig({
375
+ * chromeWebSecurity: false,
376
+ * e2e: {
377
+ * ...nxPreset,
378
+ * ...defaultCypressConfig(__dirname),
379
+ * async setupNodeEvents(on, config: CypressPluginConfig) {
380
+ * await nxPreset.setupNodeEvents?.(on, config);
381
+ * return setupPlugins(on, config, formatter, installHarGenerator);
382
+ * },
383
+ * },
384
+ * });
385
+ * ```
515
386
  */
516
- function setupE2E() {
517
- setupHarRecording();
518
- // eslint-disable-next-line @typescript-eslint/no-require-imports
519
- require("cypress-terminal-report/src/installLogsCollector")({
520
- xhr: {
521
- printHeaderData: true,
522
- printRequestData: true,
387
+ function createNxPreset(filename) {
388
+ return nxE2EPreset(filename, {
389
+ bundler: "vite",
390
+ cypressDir: "cypress",
391
+ viteConfigOverrides: {
392
+ configFile: false,
393
+ plugins: [nxViteTsPaths()],
523
394
  },
524
395
  });
525
- Cypress.on("uncaught:exception", (err) => {
526
- // eslint-disable-next-line no-console
527
- console.log("Caught Error: ", err);
528
- // returning false here prevents Cypress from
529
- // failing the test
530
- return false;
531
- });
532
- }
533
- const originalDescribe = global.describe;
534
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
535
- if (originalDescribe) {
536
- const codeowner = Cypress.env("codeowner");
537
- const addOwnerToTitle = (title) => {
538
- return codeowner ? title + ` [${codeowner}]` : title;
539
- };
540
- function patchedDescribe(title, fn) {
541
- return originalDescribe(addOwnerToTitle(title), fn);
542
- }
543
- patchedDescribe.only = (title, fn) => {
544
- return originalDescribe.only(addOwnerToTitle(title), fn);
545
- };
546
- patchedDescribe.skip = (title, fn) => {
547
- return originalDescribe.skip(addOwnerToTitle(title), fn);
548
- };
549
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
550
- global.describe = patchedDescribe;
551
396
  }
552
397
 
553
- export { createLogFile, defaultCypressConfig, setupDefaultCommands, setupE2E, setupHarRecording, setupPlugins, writeFileWithPrettier };
398
+ export { createLogFile, createNxPreset, defaultCypressConfig, setupPlugins, writeFileWithPrettier };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/iris-app-e2e",
3
- "version": "1.8.86",
3
+ "version": "1.8.88-alpha-c57027e60fa.0",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "generators": "./generators.json",
@@ -10,10 +10,20 @@
10
10
  "dependencies": {
11
11
  "@neuralegion/cypress-har-generator": "^5.17.0",
12
12
  "@nx/cypress": "22.4.4",
13
+ "@nx/devkit": "22.4.4",
14
+ "@nx/vite": "22.4.4",
13
15
  "cypress-terminal-report": "7.0.3",
14
16
  "node-xlsx": "^0.23.0",
15
- "prettier": "^3.4.2",
16
- "@nx/devkit": "22.4.4"
17
+ "prettier": "^3.4.2"
18
+ },
19
+ "exports": {
20
+ "./package.json": "./package.json",
21
+ ".": {
22
+ "module": "./index.esm.js",
23
+ "types": "./index.d.ts",
24
+ "import": "./index.cjs.mjs",
25
+ "default": "./index.cjs.js"
26
+ }
17
27
  },
18
28
  "module": "./index.esm.js",
19
29
  "main": "./index.cjs.js",
package/src/index.d.ts CHANGED
@@ -1,6 +1,13 @@
1
- export * from "./commands/defaultCommands";
1
+ /**
2
+ * Node.js-compatible exports for Cypress config files (cypress.config.ts).
3
+ * These can be safely imported in Node.js context during config processing.
4
+ *
5
+ * For browser-only exports (commands, setup functions that use Cypress global),
6
+ * import from "@trackunit/iris-app-e2e/support" instead.
7
+ */
2
8
  export * from "./plugins/createLogFile";
3
9
  export * from "./plugins/defaultPlugins";
10
+ export * from "./plugins/nxPreset";
4
11
  export * from "./plugins/writeFileWithPrettier";
5
- export * from "./setup/defaultE2ESetup";
6
- export * from "./setup/setupHarRecording";
12
+ export type { CypressPluginConfig, E2EBehaviorConfig, E2EConfigOptions, E2EPluginConfig, E2EProjectConfig, } from "./plugins/defaultPlugins";
13
+ export type { Formatter } from "./plugins/writeFileWithPrettier";
@@ -0,0 +1,27 @@
1
+ import { nxE2EPreset } from "@nx/cypress/plugins/cypress-preset";
2
+ /**
3
+ * Creates the standard NX E2E preset configuration for Cypress.
4
+ * This wraps the @nx/cypress preset with our default Vite configuration.
5
+ *
6
+ * @param filename - Pass `__filename` from the calling cypress.config.ts
7
+ * @example
8
+ * ```ts
9
+ * import { createNxPreset, CypressPluginConfig, defaultCypressConfig, setupPlugins } from "@trackunit/iris-app-e2e";
10
+ * import { defineConfig } from "cypress";
11
+ *
12
+ * const nxPreset = createNxPreset(__filename);
13
+ *
14
+ * export default defineConfig({
15
+ * chromeWebSecurity: false,
16
+ * e2e: {
17
+ * ...nxPreset,
18
+ * ...defaultCypressConfig(__dirname),
19
+ * async setupNodeEvents(on, config: CypressPluginConfig) {
20
+ * await nxPreset.setupNodeEvents?.(on, config);
21
+ * return setupPlugins(on, config, formatter, installHarGenerator);
22
+ * },
23
+ * },
24
+ * });
25
+ * ```
26
+ */
27
+ export declare function createNxPreset(filename: string): ReturnType<typeof nxE2EPreset>;
@@ -1,3 +1,4 @@
1
+ import "@neuralegion/cypress-har-generator/commands";
1
2
  /**
2
3
  * Sets up HAR (HTTP Archive) recording for E2E tests.
3
4
  * Records network activity and saves HAR files for failed tests.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Browser-only exports for Cypress support files.
3
+ * These modules depend on the Cypress global and must only be imported
4
+ * in Cypress support files, NOT in cypress.config.ts or other Node.js contexts.
5
+ */
6
+ export * from "./commands/defaultCommands";
7
+ export * from "./setup/defaultE2ESetup";
8
+ export * from "./setup/setupHarRecording";