racejar 1.0.2 → 1.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.0](https://github.com/portabletext/editor/compare/racejar-v1.0.3...racejar-v1.1.0) (2024-12-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * **`compileFeature`:** allow passing context to each `step` ([05d6a23](https://github.com/portabletext/editor/commit/05d6a233d18eada7a46ff52520155f22d58f6ae4))
9
+ * add initial version of `racejar/playwright` ([2cac384](https://github.com/portabletext/editor/commit/2cac3846db0f01a157c00d55b0b7ba802278fe0a))
10
+
11
+ ## [1.0.3](https://github.com/portabletext/editor/compare/racejar-v1.0.2...racejar-v1.0.3) (2024-12-01)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * fix type error when defining inline steps without using generics ([d371044](https://github.com/portabletext/editor/commit/d371044dae46e87188bfc52cbadd8708748bb0ce))
17
+
3
18
  ## [1.0.2](https://github.com/portabletext/editor/compare/racejar-v1.0.1...racejar-v1.0.2) (2024-11-29)
4
19
 
5
20
 
package/README.md CHANGED
@@ -130,13 +130,13 @@ Feature({
130
130
  When greeting the person
131
131
  Then the greeting is "Hello, Herman!"`,
132
132
  stepDefinitions: [
133
- Given<Context, string>('the person {string}', (context, person) => {
133
+ Given('the person {string}', (context: Context, person: string) => {
134
134
  context.person = person
135
135
  }),
136
- When<Context>('greeting the person', (context) => {
136
+ When('greeting the person', (context: Context) => {
137
137
  context.greeting = greet(context.person)
138
138
  }),
139
- Then<Context, string>('the greeting is {string}', (context, greeting) => {
139
+ Then('the greeting is {string}', (context: Context, greeting: string) => {
140
140
  expect(context.greeting).toBe(greeting)
141
141
  }),
142
142
  ],
@@ -19,13 +19,13 @@ Feature({
19
19
  When greeting the person
20
20
  Then the greeting is "Hello, Herman!"`,
21
21
  stepDefinitions: [
22
- Given<Context, string>('the person {string}', (context, person) => {
22
+ Given('the person {string}', (context: Context, person: string) => {
23
23
  context.person = person
24
24
  }),
25
- When<Context>('greeting the person', (context) => {
25
+ When('greeting the person', (context: Context) => {
26
26
  context.greeting = greet(context.person)
27
27
  }),
28
- Then<Context, string>('the greeting is {string}', (context, greeting) => {
28
+ Then('the greeting is {string}', (context: Context, greeting: string) => {
29
29
  expect(context.greeting).toBe(greeting)
30
30
  }),
31
31
  ],
@@ -0,0 +1,35 @@
1
+ import {expect} from '@playwright/test'
2
+ import {Feature, type PlaywrightContext} from '../src/playwright'
3
+ import {Given, Then, When} from '../src/step-definitions'
4
+
5
+ type Context = PlaywrightContext
6
+
7
+ Feature({
8
+ featureText: `
9
+ Feature: Playwright Homepage
10
+ Scenario: Navigating to Get Started
11
+ Given the homepage
12
+ When clicking the "Get started" link
13
+ Then the heading is "Installation"`,
14
+ stepDefinitions: [
15
+ Given('the homepage', async (context: Context) => {
16
+ await context.playwright.page.goto('https://playwright.dev/')
17
+ }),
18
+ When(
19
+ 'clicking the {string} link',
20
+ async (context: Context, linkName: string) => {
21
+ await context.playwright.page
22
+ .getByRole('link', {name: linkName})
23
+ .click()
24
+ },
25
+ ),
26
+ Then(
27
+ 'the heading is {string}',
28
+ async (context: Context, heading: string) => {
29
+ await expect(
30
+ context.playwright.page.getByRole('heading', {name: heading}),
31
+ ).toBeVisible()
32
+ },
33
+ ),
34
+ ],
35
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "racejar",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "A testing framework agnostic Gherkin driver",
5
5
  "keywords": [
6
6
  "cucumber",
@@ -30,6 +30,10 @@
30
30
  "default": "./src/jest/index.ts",
31
31
  "types": "./src/jest/index.ts"
32
32
  },
33
+ "./playwright": {
34
+ "default": "./src/playwright/index.ts",
35
+ "types": "./src/playwright/index.ts"
36
+ },
33
37
  "./vitest": {
34
38
  "default": "./src/vitest/index.ts",
35
39
  "types": "./src/vitest/index.ts"
@@ -40,12 +44,14 @@
40
44
  "@cucumber/gherkin": "^30.0.4",
41
45
  "@cucumber/messages": "^27.0.2",
42
46
  "@jest/globals": "^29.7.0",
47
+ "@playwright/test": "^1.49.0",
43
48
  "@sanity/pkg-utils": "^6.11.13",
44
49
  "typescript": "5.7.2",
45
50
  "vitest": "^2.1.5"
46
51
  },
47
52
  "peerDependencies": {
48
53
  "@jest/globals": "^29.7.0",
54
+ "@playwright/test": "^1.49.0",
49
55
  "vitest": "^2.1.5"
50
56
  },
51
57
  "scripts": {
@@ -5,28 +5,29 @@ import {
5
5
  } from '@cucumber/cucumber-expressions'
6
6
  import * as Gherkin from '@cucumber/gherkin'
7
7
  import * as Messages from '@cucumber/messages'
8
- import type {
9
- StepDefinition,
10
- StepDefinitionCallbackParameters,
11
- } from './step-definitions'
8
+ import type {StepDefinition} from './step-definitions'
12
9
 
13
10
  /**
14
11
  * @public
15
12
  */
16
- export type CompiledFeature = {
17
- name: string
18
- tag?: 'only' | 'skip'
19
- scenarios: Array<{
13
+ export type CompiledFeature<TStepContext extends Record<string, any> = object> =
14
+ {
20
15
  name: string
21
16
  tag?: 'only' | 'skip'
22
- steps: Array<() => Promise<void> | void>
23
- }>
24
- }
17
+ scenarios: Array<{
18
+ name: string
19
+ tag?: 'only' | 'skip'
20
+ steps: Array<(stepContext?: TStepContext) => Promise<void> | void>
21
+ }>
22
+ }
25
23
 
26
24
  /**
27
25
  * @public
28
26
  */
29
- export function compileFeature<TContext extends Record<string, any> = object>({
27
+ export function compileFeature<
28
+ TContext extends Record<string, any> = object,
29
+ TStepContext extends Record<string, any> = object,
30
+ >({
30
31
  featureText,
31
32
  stepDefinitions,
32
33
  parameterTypes,
@@ -34,7 +35,7 @@ export function compileFeature<TContext extends Record<string, any> = object>({
34
35
  featureText: string
35
36
  stepDefinitions: Array<StepDefinition<TContext, any, any, any>>
36
37
  parameterTypes?: Array<ParameterType<unknown>>
37
- }): CompiledFeature {
38
+ }): CompiledFeature<TStepContext> {
38
39
  const uuidFn = Messages.IdGenerator.uuid()
39
40
  const builder = new Gherkin.AstBuilder(uuidFn)
40
41
  const matcher = new Gherkin.GherkinClassicTokenMatcher()
@@ -116,11 +117,15 @@ export function compileFeature<TContext extends Record<string, any> = object>({
116
117
  throw new Error(`Multiple implementations found for step: ${step.text}`)
117
118
  }
118
119
 
119
- const args = matchingStep.args.map((arg) =>
120
- arg.getValue(matchingStep),
121
- ) as StepDefinitionCallbackParameters<any, any, any>
120
+ const args = matchingStep.args.map((arg) => arg.getValue(matchingStep))
122
121
 
123
- return () => matchingStep.callback(context, ...args)
122
+ return (stepContext: TStepContext | undefined) =>
123
+ matchingStep.callback(
124
+ Object.assign(context, stepContext),
125
+ args[0],
126
+ args[1],
127
+ args[2],
128
+ )
124
129
  })
125
130
 
126
131
  return {
@@ -0,0 +1 @@
1
+ export * from './playwright-gherkin-driver'
@@ -0,0 +1,64 @@
1
+ import type {ParameterType} from '@cucumber/cucumber-expressions'
2
+ import {test, type BrowserContext, type Page} from '@playwright/test'
3
+ import {compileFeature} from '../compile-feature'
4
+ import type {StepDefinition} from '../step-definitions'
5
+
6
+ /**
7
+ * @public
8
+ */
9
+ export type PlaywrightContext = {
10
+ playwright: {
11
+ page: Page
12
+ context: BrowserContext
13
+ }
14
+ }
15
+
16
+ /**
17
+ * @public
18
+ */
19
+ export function Feature<
20
+ TContext extends PlaywrightContext = PlaywrightContext,
21
+ >({
22
+ featureText,
23
+ stepDefinitions,
24
+ parameterTypes,
25
+ }: {
26
+ featureText: string
27
+ stepDefinitions: Array<StepDefinition<TContext, any, any, any>>
28
+ parameterTypes?: Array<ParameterType<unknown>>
29
+ }) {
30
+ const feature = compileFeature({
31
+ featureText,
32
+ stepDefinitions,
33
+ parameterTypes,
34
+ })
35
+
36
+ const describeFn =
37
+ feature.tag === 'only'
38
+ ? test.describe.only
39
+ : feature.tag === 'skip'
40
+ ? test.describe.skip
41
+ : test.describe
42
+
43
+ describeFn(feature.name, async () => {
44
+ for (const scenario of feature.scenarios) {
45
+ const testFn =
46
+ scenario.tag === 'only'
47
+ ? test.only
48
+ : scenario.tag === 'skip'
49
+ ? test.skip
50
+ : test
51
+
52
+ testFn(scenario.name, async ({page, context}) => {
53
+ for (const step of scenario.steps) {
54
+ await step({
55
+ playwright: {
56
+ page,
57
+ context,
58
+ },
59
+ })
60
+ }
61
+ })
62
+ }
63
+ })
64
+ }
@@ -1,30 +1,27 @@
1
1
  /**
2
2
  * @public
3
3
  */
4
- export type StepDefinitionCallbackParameters<
4
+ export type StepDefinitionCallback<
5
+ TContext extends Record<string, any> = object,
5
6
  TParamA = undefined,
6
7
  TParamB = undefined,
7
8
  TParamC = undefined,
8
9
  > = TParamA extends undefined
9
- ? []
10
+ ? (context: TContext) => Promise<void> | void
10
11
  : TParamB extends undefined
11
- ? [TParamA]
12
+ ? (context: TContext, paramA: TParamA) => Promise<void> | void
12
13
  : TParamC extends undefined
13
- ? [TParamA, TParamB]
14
- : [TParamA, TParamB, TParamC]
15
-
16
- /**
17
- * @public
18
- */
19
- export type StepDefinitionCallback<
20
- TContext extends Record<string, any> = object,
21
- TParamA = undefined,
22
- TParamB = undefined,
23
- TParamC = undefined,
24
- > = (
25
- context: TContext,
26
- ...args: StepDefinitionCallbackParameters<TParamA, TParamB, TParamC>
27
- ) => Promise<void> | void
14
+ ? (
15
+ context: TContext,
16
+ paramA: TParamA,
17
+ paramB: TParamB,
18
+ ) => Promise<void> | void
19
+ : (
20
+ context: TContext,
21
+ paramA: TParamA,
22
+ paramB: TParamB,
23
+ paramC: TParamC,
24
+ ) => Promise<void> | void
28
25
 
29
26
  /**
30
27
  * @public
@@ -6,12 +6,14 @@ export default defineWorkspace([
6
6
  plugins: [],
7
7
  test: {
8
8
  name: 'unit',
9
+ exclude: ['example-playwright'],
9
10
  },
10
11
  },
11
12
  {
12
13
  plugins: [],
13
14
  test: {
14
15
  name: 'chromium',
16
+ exclude: ['example-playwright'],
15
17
  },
16
18
  },
17
19
  ])