@qavajs/cypress-runner-adapter 1.10.0 → 1.11.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
@@ -30,6 +30,47 @@ module.exports = defineConfig({
30
30
  });
31
31
  ```
32
32
 
33
+ ### TypeScript
34
+
35
+ TypeScript support is built-in. Point `supportFile` at a `.ts` file and the adapter will compile it automatically:
36
+
37
+ ```javascript
38
+ const { defineConfig } = require('cypress');
39
+ const cucumber = require('@qavajs/cypress-runner-adapter/adapter');
40
+
41
+ module.exports = defineConfig({
42
+ e2e: {
43
+ specPattern: 'cypress/feature/**/*.feature',
44
+ supportFile: 'cypress/support/e2e.ts',
45
+ setupNodeEvents(on, config) {
46
+ on('file:preprocessor', cucumber);
47
+ },
48
+ },
49
+ });
50
+ ```
51
+
52
+ ```typescript
53
+ // cypress/support/e2e.ts
54
+ import { Given, When, Then, setWorldConstructor, World, WorldOptions } from '@qavajs/cypress-runner-adapter';
55
+
56
+ class CustomWorld extends World {
57
+ myValue: string | null;
58
+
59
+ constructor(options: WorldOptions) {
60
+ super(options);
61
+ this.myValue = null;
62
+ }
63
+ }
64
+
65
+ setWorldConstructor(CustomWorld);
66
+
67
+ Given('I navigate to {string}', function (this: CustomWorld, url: string) {
68
+ cy.visit(url);
69
+ });
70
+ ```
71
+
72
+ A `tsconfig.json` is not required but recommended. The adapter uses `transpileOnly: true` so type errors will not block the test run.
73
+
33
74
  ## Step Definitions
34
75
 
35
76
  Define steps in your support file (e.g. `cypress/support/e2e.js`):
package/adapter/index.js CHANGED
@@ -2,7 +2,26 @@ const { mkdirSync, writeFileSync, readFileSync } = require('node:fs');
2
2
  const { dirname } = require('node:path');
3
3
  const { randomUUID } = require('node:crypto');
4
4
  const { AstBuilder, compile, GherkinClassicTokenMatcher, Parser } = require('@cucumber/gherkin');
5
- const webpackPreprocessor = require('@cypress/webpack-preprocessor')();
5
+ const webpackPreprocessor = require('@cypress/webpack-preprocessor')({
6
+ webpackOptions: {
7
+ mode: 'development',
8
+ resolve: { extensions: ['.ts', '.js'] },
9
+ module: {
10
+ rules: [
11
+ {
12
+ test: /\.tsx?$/,
13
+ exclude: [/node_modules/],
14
+ use: [{ loader: 'ts-loader', options: { transpileOnly: true } }]
15
+ },
16
+ {
17
+ test: /\.jsx?$/,
18
+ exclude: [/node_modules/],
19
+ use: [{ loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } }]
20
+ }
21
+ ]
22
+ }
23
+ }
24
+ });
6
25
  const tagExpressionParser = require('@cucumber/tag-expressions').default;
7
26
  const makeMochaTestDescribe = require('./make_mocha_tests_describe');
8
27
  const makeMochaTestIt = require('./make_mocha_tests_it');
@@ -50,7 +50,7 @@ module.exports = function makeMochaTest(tests) {
50
50
  step: { text, argument },
51
51
  world: this
52
52
  });
53
- step.code.apply(this, parameters);
53
+ return step.code.apply(this, parameters);
54
54
  }
55
55
 
56
56
  function executeStep(pickle, world) {
@@ -60,7 +60,7 @@ module.exports = function makeMochaTest(tests) {
60
60
  if (pickle.argument && pickle.argument.docString) {
61
61
  Cypress.log({ displayName: 'Multiline', message: pickle.argument.docString.content });
62
62
  }
63
- executeStepByText.call(world, pickle.text, pickle.argument);
63
+ return executeStepByText.call(world, pickle.text, pickle.argument);
64
64
  }
65
65
 
66
66
  if (supportCodeLibrary.beforeTestRunHookDefinitions.length > 0) {
@@ -150,7 +150,12 @@ module.exports = function makeMochaTest(tests) {
150
150
  }]);
151
151
  }
152
152
  }
153
- executeStep(step, world);
153
+ const stepResult = executeStep(step, world);
154
+ if (stepResult === 'pending' || stepResult === 'skipped') {
155
+ skip = true;
156
+ status = stepResult;
157
+ return this.skip();
158
+ }
154
159
  });
155
160
  }
156
161
  for (const afterTest of supportCodeLibrary.afterTestCaseHookDefinitions) {
@@ -58,7 +58,7 @@ module.exports = function makeMochaTest(tests) {
58
58
  step: { text, argument },
59
59
  world: this
60
60
  });
61
- step.code.apply(this, parameters);
61
+ return step.code.apply(this, parameters);
62
62
  }
63
63
 
64
64
  function executeStep(pickle, world) {
@@ -70,7 +70,7 @@ module.exports = function makeMochaTest(tests) {
70
70
  Cypress.log({ displayName: 'Multiline', message: pickle.argument.docString.content });
71
71
  }
72
72
  });
73
- executeStepByText.call(world, pickle.text, pickle.argument);
73
+ return executeStepByText.call(world, pickle.text, pickle.argument);
74
74
  }
75
75
 
76
76
  supportCodeLibrary.World.prototype.executeStep = executeStepByText;
@@ -186,7 +186,11 @@ module.exports = function makeMochaTest(tests) {
186
186
  }]);
187
187
  }
188
188
  }
189
- executeStep(step, world);
189
+ const stepResult = executeStep(step, world);
190
+ if (stepResult === 'pending' || stepResult === 'skipped') {
191
+ result.status = stepResult;
192
+ return this.skip();
193
+ }
190
194
  for (const afterStep of supportCodeLibrary.afterTestStepHookDefinitions) {
191
195
  if (afterStep.appliesToTestCase(this.step)) {
192
196
  afterStep.code.apply(world, [{
package/index.d.ts CHANGED
@@ -1,44 +1 @@
1
- declare type Expression = string | RegExp;
2
- declare type TestHookOptions = {
3
- tags?: string,
4
- name?: string
5
- };
6
- declare type StepHookOptions = {
7
- tags?: string
8
- };
9
- declare type ParameterTypeOption = {
10
- name: string,
11
- preferForRegexpMatch?: boolean,
12
- regexp: RegExp,
13
- transformer?: Function,
14
- useForSnippets?: boolean
15
- }
16
- export function defineStep(keyword: string, expression: Expression, fn: Function): void;
17
- export function Given(expression: Expression, fn: Function): void;
18
- export function When(expression: Expression, fn: Function): void;
19
- export function Then(expression: Expression, fn: Function): void;
20
- export function Before(fn: Function): void;
21
- export function Before(options: TestHookOptions, fn: Function): void;
22
- export function After(fn: Function): void;
23
- export function After(options: TestHookOptions, fn: Function): void;
24
- export function BeforeStep(fn: Function): void;
25
- export function BeforeStep(options: StepHookOptions, fn: Function): void;
26
- export function AfterStep(fn: Function): void;
27
- export function AfterStep(options: StepHookOptions, fn: Function): void;
28
- export function BeforeAll(fn: Function): void;
29
- export function AfterAll(fn: Function): void;
30
- export function setWorldConstructor(world: IWorld): void;
31
- export function defineParameterType(option: ParameterTypeOption): void;
32
- export function setDefaultTimeout(milliseconds: number): void;
33
- export function Template(template: (...args: any[]) => string): () => void;
34
- export class World {
35
- log: (...args: any) => void;
36
- attach: (...args: any) => void;
37
- link: (...args: any) => void;
38
- executeStep(text: string, argument?: any): void;
39
- constructor(options: {
40
- log: (...args: any) => void;
41
- attach: (...args: any) => void;
42
- link: (...args: any) => void;
43
- });
44
- }
1
+ export * from './supportCodeLibrary/index';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qavajs/cypress-runner-adapter",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "main": "supportCodeLibrary/index.js",
5
5
  "exports": {
6
6
  ".": "./supportCodeLibrary/index.js",
@@ -16,7 +16,11 @@
16
16
  "debug": "cypress open --config-file test/cypress.config.js",
17
17
  "test": "cypress run --config-file test/cypress.config.js",
18
18
  "debug:it": "MODE=it cypress open --config-file test/cypress.config.js",
19
- "test:it": "MODE=it cypress run --config-file test/cypress.config.js"
19
+ "test:it": "MODE=it cypress run --config-file test/cypress.config.js",
20
+ "debug:ts": "cypress open --config-file test/cypress-ts.config.js",
21
+ "test:ts": "cypress run --config-file test/cypress-ts.config.js",
22
+ "debug:ts:it": "MODE=it cypress open --config-file test/cypress-ts.config.js",
23
+ "test:ts:it": "MODE=it cypress run --config-file test/cypress-ts.config.js"
20
24
  },
21
25
  "license": "MIT",
22
26
  "description": "feature file preprocessor",
@@ -35,10 +39,12 @@
35
39
  "@cucumber/cucumber-expressions": "^19.0.0",
36
40
  "@cucumber/gherkin": "^39.1.0",
37
41
  "@cucumber/tag-expressions": "^9.1.0",
38
- "@cypress/webpack-preprocessor": "^7.1.0"
42
+ "@cypress/webpack-preprocessor": "^7.1.0",
43
+ "ts-loader": "^9.5.7"
39
44
  },
40
45
  "devDependencies": {
41
- "cypress": "^15.14.2"
46
+ "cypress": "^15.14.2",
47
+ "typescript": "^6.0.3"
42
48
  },
43
49
  "keywords": [
44
50
  "cypress",
@@ -50,4 +56,4 @@
50
56
  "test",
51
57
  "test-automation"
52
58
  ]
53
- }
59
+ }
@@ -0,0 +1,112 @@
1
+ export type Expression = string | RegExp;
2
+
3
+ export class DataTable {
4
+ constructor(sourceTable: string[][] | { rows: { cells: { value: string }[] }[] });
5
+ raw(): string[][];
6
+ rows(): string[][];
7
+ hashes(): Record<string, string>[];
8
+ rowsHash(): Record<string, string>;
9
+ transpose(): DataTable;
10
+ }
11
+
12
+ export interface GherkinDocument {
13
+ uri?: string;
14
+ feature?: {
15
+ name: string;
16
+ description: string;
17
+ tags: { name: string }[];
18
+ children: object[];
19
+ };
20
+ comments: object[];
21
+ }
22
+
23
+ export interface Pickle {
24
+ id: string;
25
+ uri: string;
26
+ name: string;
27
+ language: string;
28
+ steps: { id: string; text: string; argument?: object }[];
29
+ tags: { name: string; astNodeId: string }[];
30
+ astNodeIds: string[];
31
+ }
32
+
33
+ export interface TestStepResult {
34
+ status: string;
35
+ duration?: { seconds: number; nanos: number };
36
+ message?: string;
37
+ }
38
+
39
+ export interface TestCaseHookParams {
40
+ gherkinDocument: GherkinDocument;
41
+ pickle: Pickle;
42
+ testCaseStartedId: string;
43
+ willBeRetried: boolean;
44
+ result?: TestStepResult;
45
+ error?: Error;
46
+ }
47
+
48
+ export interface TestStepHookParams {
49
+ gherkinDocument: GherkinDocument;
50
+ pickle: Pickle;
51
+ testCaseStartedId: string;
52
+ result?: TestStepResult;
53
+ error?: Error;
54
+ }
55
+
56
+ export interface WorldOptions {
57
+ log: (...args: any[]) => void;
58
+ attach: (data: string, mediaType?: string) => void;
59
+ link: (url: string, text?: string) => void;
60
+ }
61
+
62
+ export class World {
63
+ log(...args: any[]): void;
64
+ attach(data: string, mediaType?: string): void;
65
+ link(url: string, text?: string): void;
66
+ executeStep(text: string, argument?: DataTable | string): void;
67
+ constructor(options: WorldOptions);
68
+ }
69
+
70
+ type StepFn<W extends World = World> = (this: W, ...args: any[]) => any;
71
+
72
+ export function defineStep<W extends World = World>(keyword: string, expression: Expression, fn: StepFn<W>): void;
73
+ export function Given<W extends World = World>(expression: Expression, fn: StepFn<W>): void;
74
+ export function When<W extends World = World>(expression: Expression, fn: StepFn<W>): void;
75
+ export function Then<W extends World = World>(expression: Expression, fn: StepFn<W>): void;
76
+
77
+ type TestCaseHookFn = (this: World, params: TestCaseHookParams) => any;
78
+ type TestStepHookFn = (this: World, params: TestStepHookParams) => any;
79
+ type TestRunHookFn = (this: World) => any;
80
+
81
+ export interface TestCaseHookOptions {
82
+ tags?: string;
83
+ name?: string;
84
+ }
85
+
86
+ export interface TestStepHookOptions {
87
+ tags?: string;
88
+ }
89
+
90
+ export function Before(fn: TestCaseHookFn): void;
91
+ export function Before(options: TestCaseHookOptions, fn: TestCaseHookFn): void;
92
+ export function After(fn: TestCaseHookFn): void;
93
+ export function After(options: TestCaseHookOptions, fn: TestCaseHookFn): void;
94
+ export function BeforeStep(fn: TestStepHookFn): void;
95
+ export function BeforeStep(options: TestStepHookOptions, fn: TestStepHookFn): void;
96
+ export function AfterStep(fn: TestStepHookFn): void;
97
+ export function AfterStep(options: TestStepHookOptions, fn: TestStepHookFn): void;
98
+ export function BeforeAll(fn: TestRunHookFn): void;
99
+ export function AfterAll(fn: TestRunHookFn): void;
100
+
101
+ export interface ParameterTypeOption {
102
+ name: string;
103
+ regexp: RegExp;
104
+ transformer?: (...args: string[]) => any;
105
+ useForSnippets?: boolean;
106
+ preferForRegexpMatch?: boolean;
107
+ }
108
+
109
+ export function defineParameterType(option: ParameterTypeOption): void;
110
+ export function setWorldConstructor(world: new (...args: any[]) => World): void;
111
+ export function setDefaultTimeout(milliseconds: number): void;
112
+ export function Template(template: (...args: any[]) => string): (...args: any[]) => void;