@letsrunit/bdd 0.9.1 → 0.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/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/registry.ts +11 -1
- package/src/steps/assert.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -45,6 +45,9 @@ function createRegistry() {
|
|
|
45
45
|
return _entries.map(({ type: type2, expression, fn, comment }) => ({ type: type2, expression, fn, comment }));
|
|
46
46
|
},
|
|
47
47
|
defineStep(type2, expression, fn, comment) {
|
|
48
|
+
const source = String(expression);
|
|
49
|
+
const duplicate = _entries.some((entry) => entry.type === type2 && String(entry.expression) === source);
|
|
50
|
+
if (duplicate) return;
|
|
48
51
|
const expr = typeof expression === "string" ? new CucumberExpression(sanitizeStepDefinition(expression), _paramRegistry) : new RegularExpression(expression, _paramRegistry);
|
|
49
52
|
_entries.push({ type: type2, expression, fn, comment, expr });
|
|
50
53
|
},
|
|
@@ -68,7 +71,9 @@ function createRegistry() {
|
|
|
68
71
|
}
|
|
69
72
|
};
|
|
70
73
|
}
|
|
71
|
-
var
|
|
74
|
+
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("letsrunit.bdd.registry");
|
|
75
|
+
var registryStore = globalThis;
|
|
76
|
+
var registry = registryStore[REGISTRY_KEY] ?? (registryStore[REGISTRY_KEY] = createRegistry());
|
|
72
77
|
function Given(expression, fn, comment) {
|
|
73
78
|
const def = { type: "Given", expression, fn, comment };
|
|
74
79
|
registry.defineStep("Given", expression, fn, comment);
|
|
@@ -91,7 +96,7 @@ function expectOrNot(actual, toBe) {
|
|
|
91
96
|
// src/steps/assert.ts
|
|
92
97
|
var WAIT_TIMEOUT = 5e3;
|
|
93
98
|
Then(
|
|
94
|
-
"
|
|
99
|
+
"the page {contains|does not contain} {locator}",
|
|
95
100
|
async function(visible, selector) {
|
|
96
101
|
const el = await fuzzyLocator(this.page, selector);
|
|
97
102
|
await expectOrNot(el, visible).toBeVisible({ timeout: WAIT_TIMEOUT });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parameters.ts","../src/registry.ts","../src/utils/test-helpers.ts","../src/steps/assert.ts","../src/utils/get-lang.ts","../src/steps/navigation.ts","../src/steps/mouse.ts","../src/steps/form.ts","../src/steps/keyboard.ts","../src/steps/mailbox.ts","../src/steps/clipboard.ts","../src/utils/file.ts"],"names":["type","contain","expect","fuzzyLocator","TIMEOUT","check","focus","DELAY","sleep"],"mappings":"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","file":"index.js","sourcesContent":["import { booleanParameter, enumParameter, keysParameter, locatorParameter, valueParameter } from '@letsrunit/gherkin';\n\nexport const typeDefinitions = [\n locatorParameter(),\n valueParameter(),\n keysParameter(),\n\n booleanParameter('visible', 'hidden'),\n booleanParameter('enabled', 'disabled', /((?:en|dis)abled)/),\n booleanParameter('checked', 'unchecked', /((?:un)?checked)/),\n booleanParameter('contains', 'does not contain'),\n\n booleanParameter('check', 'uncheck', /((?:un)?check)/),\n booleanParameter('focus', 'blur'),\n\n enumParameter(['click', 'double-click', 'right-click', 'hover'], /((?:double-|right-)?click|hover)/),\n enumParameter(['mobile', 'tablet', 'desktop']),\n];\n","import {\n CucumberExpression,\n ParameterType,\n ParameterTypeRegistry,\n RegularExpression,\n} from '@cucumber/cucumber-expressions';\nimport { sanitizeStepDefinition, type ParameterTypeDefinition } from '@letsrunit/gherkin';\nimport { typeDefinitions } from './parameters';\nimport type { StepDefinition, StepHandler, StepType } from './types';\n\ninterface Entry {\n type: StepType;\n expression: string | RegExp;\n fn: StepHandler;\n comment?: string;\n expr: CucumberExpression | RegularExpression;\n}\n\nexport function createRegistry() {\n const _paramRegistry = new ParameterTypeRegistry();\n const _entries: Entry[] = [];\n\n for (const t of typeDefinitions) {\n _paramRegistry.defineParameterType(\n new ParameterType(t.name, t.regexp, null, t.transformer as any, t.useForSnippets),\n );\n }\n\n return {\n /** IStepRegistry-compatible defs (source = String(expression), no raw expr). */\n get defs() {\n return _entries.map(({ type, expression, fn, comment }) => ({\n type,\n source: String(expression),\n fn,\n comment,\n }));\n },\n\n /** Raw step definitions with original expression — used by define.ts for Cucumber registration. */\n get definitions(): StepDefinition[] {\n return _entries.map(({ type, expression, fn, comment }) => ({ type, expression, fn, comment }));\n },\n\n defineStep(type: StepType, expression: string | RegExp, fn: StepHandler, comment?: string): void {\n const expr =\n typeof expression === 'string'\n ? new CucumberExpression(sanitizeStepDefinition(expression), _paramRegistry)\n : new RegularExpression(expression, _paramRegistry);\n _entries.push({ type, expression, fn, comment, expr });\n },\n\n defineParameterType(type: ParameterTypeDefinition<unknown>): void {\n _paramRegistry.defineParameterType(\n new ParameterType(type.name, type.regexp, null, type.transformer, type.useForSnippets),\n );\n },\n\n match(text: string) {\n for (const entry of _entries) {\n const args = entry.expr.match(text);\n if (args) {\n return {\n def: { type: entry.type, source: String(entry.expression), fn: entry.fn, comment: entry.comment },\n values: args.map((a) => a.getValue(null)),\n args,\n };\n }\n }\n return null;\n },\n };\n}\n\nexport const registry = createRegistry();\n\nexport function Given(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n const def: StepDefinition = { type: 'Given', expression, fn, comment };\n registry.defineStep('Given', expression, fn, comment);\n return def;\n}\n\nexport function When(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n const def: StepDefinition = { type: 'When', expression, fn, comment };\n registry.defineStep('When', expression, fn, comment);\n return def;\n}\n\nexport function Then(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n const def: StepDefinition = { type: 'Then', expression, fn, comment };\n registry.defineStep('Then', expression, fn, comment);\n return def;\n}\n","import { expect, type Expect } from '@playwright/test';\n\nexport function expectOrNot<T>(\n actual: T,\n toBe: boolean\n): ReturnType<Expect<T>> | ReturnType<ReturnType<Expect<T>>['not']> {\n return toBe ? expect(actual) : expect(actual).not;\n}\n","import { fuzzyLocator } from '@letsrunit/playwright';\nimport { Then } from '../registry';\nimport { expectOrNot } from '../utils/test-helpers';\n\nconst WAIT_TIMEOUT = 5000;\n\nexport const see = Then(\n 'The page {contains|does not contain} {locator}',\n async function (visible: boolean, selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n await expectOrNot(el, visible).toBeVisible({ timeout: WAIT_TIMEOUT });\n },\n);\n\nexport const contain = Then(\n '{locator} {contains|does not contain} {locator}',\n async function (selector: string, contain: boolean, child: string) {\n const el = await fuzzyLocator(this.page, selector);\n const childElement = el.locator(child);\n await expectOrNot(childElement, contain).toBeAttached({ timeout: WAIT_TIMEOUT });\n },\n);\n","import type { Snapshot } from '@letsrunit/playwright';\nimport { Page } from '@playwright/test';\nimport ISO6391 from 'iso-639-1';\nimport metascraper from 'metascraper';\nimport metascraperLang from 'metascraper-lang';\n\nconst scrapeLang = metascraper([metascraperLang()]);\n\nexport async function getLang(\n page: Pick<Page, 'content' | 'url'> | Snapshot,\n): Promise<{ code: string; name: string} | null> {\n const html = 'html' in page ? page.html : await page.content();\n const url = typeof page.url === 'function' ? page.url() : page.url;\n\n const { lang = null } = await scrapeLang({ html, url });\n if (!lang) return null;\n\n const code = lang.substring(0, 2);\n const name = ISO6391.getName(code) || code;\n\n return { code, name };\n}\n","import { suppressInterferences, waitForIdle } from '@letsrunit/playwright';\nimport { eventually, pathRegexp, splitUrl } from '@letsrunit/utils';\nimport { expect } from '@playwright/test';\nimport { World } from '../types';\nimport { getLang } from '../utils/get-lang';\nimport { Given, Then, When } from '../registry';\n\nasync function openPage(world: World, path: string): Promise<void> {\n const { page } = world;\n\n const result = await page.goto(path);\n expect(result?.status()).toBeLessThan(400);\n\n await waitForIdle(page);\n\n world.lang ??= (await getLang(page)) || undefined;\n}\n\nexport const navHome = Given(\"I'm on the homepage\", async function () {\n await openPage(this, '/');\n});\n\nexport const navPath = Given(\"I'm on page {string}\", async function (path: string) {\n await openPage(this, path);\n});\n\nexport const popupClosed = Given('all popups are closed', async function (){\n await suppressInterferences(this.page, { lang: this.lang?.code });\n});\n\nexport const assertPath = Then('I should be on page {string}', async function (expectedPath: string) {\n await eventually(async () => {\n const { path: actualPath } = splitUrl(this.page.url());\n\n if (expectedPath.includes(':')) {\n const { regexp, names } = pathRegexp(expectedPath);\n\n expect(actualPath, `Expected path ${actualPath} to match pattern ${expectedPath}`).toMatch(regexp);\n\n const match = actualPath.match(regexp);\n this.pathParams = Object.fromEntries(names.map((name, i) => [name, decodeURIComponent(match![i + 1])]));\n } else {\n expect(actualPath).toEqual(expectedPath);\n delete this.pathParams;\n }\n });\n});\n\nexport const back = When('I go back to the previous page', async function () {\n await this.page.goBack();\n await waitForIdle(this.page);\n});\n","import type { KeyCombo } from '@letsrunit/gherkin';\nimport { fuzzyLocator, waitAfterInteraction } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from '../registry';\n\nconst TIMEOUT = 2500;\n\ntype MouseAction = 'click' | 'double-click' | 'right-click' | 'hover';\n\nasync function press(el: Locator, action: MouseAction) {\n if (action === 'hover') {\n await el.hover({ timeout: TIMEOUT });\n } else {\n await el.click({\n button: action === 'right-click' ? 'right' : 'left',\n clickCount: action === 'double-click' ? 2 : 1,\n timeout: TIMEOUT,\n });\n }\n}\n\nexport const click = When(\n 'I {click|double-click|right-click|hover} {locator}',\n async function (action: MouseAction, selector: string) {\n const prevUrl = this.page.url();\n\n const el = await fuzzyLocator(this.page, selector);\n await press(el, action);\n\n await waitAfterInteraction(this.page, el, { prevUrl });\n },\n);\n\nexport const clickHold = When(\n 'I {click|double-click|right-click|hover} {locator} while holding {keys}',\n async function (action: MouseAction, selector: string, combo: KeyCombo) {\n const prevUrl = this.page.url();\n\n const el = await fuzzyLocator(this.page, selector);\n const keys = [...combo.modifiers, combo.key];\n\n for (const m of keys) await this.page.keyboard.down(m);\n await press(el, action);\n for (const m of keys.reverse()) await this.page.keyboard.up(m);\n\n await waitAfterInteraction(this.page, el, { prevUrl });\n },\n);\n\nexport const scroll = When('I scroll {locator} into view', async function (selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n await el.scrollIntoViewIfNeeded({ timeout: TIMEOUT });\n});\n","import { fuzzyLocator, setFieldValue } from '@letsrunit/playwright';\nimport { type Scalar, sleep } from '@letsrunit/utils';\nimport { When } from '../registry';\n\nconst TIMEOUT = 500;\nconst DELAY = 500;\n\nexport const set = When('I set {locator} to {value}', async function (selector: string, value: Scalar | Scalar[]) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, value, { timeout: TIMEOUT });\n await sleep(DELAY);\n});\n\nexport const setRange = When(\n 'I set {locator} to range of {value} to {value}',\n async function (selector: string, from: Scalar, to: Scalar) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, { from, to }, { timeout: TIMEOUT });\n await sleep(DELAY);\n },\n);\n\nexport const clear = When('I clear {locator}', async function (selector) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, null, { timeout: TIMEOUT });\n await sleep(DELAY);\n});\n\nexport const check = When(\n 'I {check|uncheck} {locator}',\n async function (check: boolean, selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, check, { timeout: TIMEOUT });\n await sleep(DELAY);\n },\n 'For checkbox input or switch component',\n);\n\nexport const focus = When('I {focus|blur} {locator}', async function (focus: boolean, selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n\n if (focus) {\n await el.focus({ timeout: TIMEOUT });\n } else {\n await el.blur({ timeout: TIMEOUT });\n }\n});\n","import type { KeyCombo } from '@letsrunit/gherkin';\nimport { sleep } from '@letsrunit/utils';\nimport { When } from '../registry';\n\nconst DELAY = 500;\n\nexport const press = When('I press {keys}', async function (combo: KeyCombo) {\n // Hold modifiers\n for (const m of combo.modifiers) await this.page.keyboard.down(m);\n\n // Press final key\n await this.page.keyboard.press(combo.key);\n\n // Release modifiers (reverse order)\n for (const m of combo.modifiers.toReversed()) await this.page.keyboard.up(m);\n\n await sleep(DELAY);\n});\n\nexport const type = When('I type {string}', async function (value: string) {\n await this.page.keyboard.type(value, { delay: 200 });\n await sleep(DELAY);\n});\n","import { receiveMail, toEml } from '@letsrunit/mailbox';\nimport { asFilename, textToHtml } from '@letsrunit/utils';\nimport { Given, Then } from '../registry';\n\nconst MAX_RECEIVE_WAIT = 120_000; // 2 minutes\n\nexport const view = Given(\n `I'm viewing an email sent to {string} with subject {string}`,\n async function (address: string, subject: string) {\n const emails = await receiveMail(address, { full: true, after: this.startTime, subject, limit: 1 });\n if (emails.length === 0) {\n throw new Error(`Did not receive an email with subject \"${subject}\"`);\n }\n\n const email = emails[0];\n\n await this.page.goto('about:blank', { waitUntil: 'load' });\n await this.page.setContent(email.html ?? textToHtml(email.text!), { waitUntil: 'domcontentloaded' });\n },\n);\n\nexport const receive = Then(\n 'I received an email sent to {string} with subject {string}',\n async function (address: string, subject: string) {\n const emails = await receiveMail(address, {\n after: this.startTime,\n full: true,\n subject,\n wait: true,\n timeout: MAX_RECEIVE_WAIT,\n limit: 1,\n });\n\n if (emails.length === 0) {\n throw new Error(`Did not receive an email with subject \"${subject}\"`);\n }\n\n const email = emails[0];\n\n this.attach(toEml(email), {\n mediaType: 'message/rfc822',\n fileName: asFilename(email.subject, 'eml'),\n });\n },\n);\n","import { fuzzyLocator } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from '../registry';\n\nconst TIMEOUT = 500;\n\nasync function copyInput(el: Locator): Promise<string | undefined> {\n try {\n return await el.inputValue();\n } catch {}\n}\n\nasync function copyLink(el: Locator): Promise<string | undefined> {\n try {\n const tag = await el.evaluate<string>((n: Element) => n.tagName.toLowerCase());\n const href = tag === 'a' ? await el.getAttribute('href') : null;\n if (href) {\n return href.startsWith('mailto:') ? href.replace(/^mailto:/i, '') : href;\n }\n } catch {}\n}\n\nasync function copyText(el: Locator): Promise<string | null> {\n return (await el.textContent()) ?? null;\n}\n\nexport const copy = When('I copy {locator} to the clipboard', async function (selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n let value = (await copyInput(el)) ?? (await copyLink(el)) ?? (await copyText(el));\n\n this.clipboard = { value };\n});\n\nexport const paste = When('I paste from the clipboard into {locator}', async function (selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n const value = this.clipboard?.value || '';\n\n await el.fill(String(value), { timeout: TIMEOUT });\n});\n","import type { Readable } from 'node:stream';\n\ntype AttachData = string | Buffer | Readable;\ntype AttachOptions = string | {\n mediaType: string;\n fileName?: string;\n};\n\nexport function toFile(data: AttachData, options?: AttachOptions): File {\n const opt =\n typeof options === 'string'\n ? { mediaType: options }\n : options ?? { mediaType: 'application/octet-stream' };\n\n const type = opt.mediaType || 'application/octet-stream';\n const name = opt.fileName || `attachment-${Date.now()}`;\n\n if (isReadable(data)) {\n throw new Error('toFile does not support Readable streams; provide Buffer or string');\n }\n\n const part = typeof data === 'string' ? data : new Uint8Array(data);\n\n return new File([part], name, { type });\n}\n\nfunction isReadable(value: unknown): value is Readable {\n return (\n !!value &&\n typeof value === 'object' &&\n (typeof (value as any).pipe === 'function' || typeof (value as any).read === 'function')\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/parameters.ts","../src/registry.ts","../src/utils/test-helpers.ts","../src/steps/assert.ts","../src/utils/get-lang.ts","../src/steps/navigation.ts","../src/steps/mouse.ts","../src/steps/form.ts","../src/steps/keyboard.ts","../src/steps/mailbox.ts","../src/steps/clipboard.ts","../src/utils/file.ts"],"names":["type","contain","expect","fuzzyLocator","TIMEOUT","check","focus","DELAY","sleep"],"mappings":"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","file":"index.js","sourcesContent":["import { booleanParameter, enumParameter, keysParameter, locatorParameter, valueParameter } from '@letsrunit/gherkin';\n\nexport const typeDefinitions = [\n locatorParameter(),\n valueParameter(),\n keysParameter(),\n\n booleanParameter('visible', 'hidden'),\n booleanParameter('enabled', 'disabled', /((?:en|dis)abled)/),\n booleanParameter('checked', 'unchecked', /((?:un)?checked)/),\n booleanParameter('contains', 'does not contain'),\n\n booleanParameter('check', 'uncheck', /((?:un)?check)/),\n booleanParameter('focus', 'blur'),\n\n enumParameter(['click', 'double-click', 'right-click', 'hover'], /((?:double-|right-)?click|hover)/),\n enumParameter(['mobile', 'tablet', 'desktop']),\n];\n","import {\n CucumberExpression,\n ParameterType,\n ParameterTypeRegistry,\n RegularExpression,\n} from '@cucumber/cucumber-expressions';\nimport { sanitizeStepDefinition, type ParameterTypeDefinition } from '@letsrunit/gherkin';\nimport { typeDefinitions } from './parameters';\nimport type { StepDefinition, StepHandler, StepType } from './types';\n\ninterface Entry {\n type: StepType;\n expression: string | RegExp;\n fn: StepHandler;\n comment?: string;\n expr: CucumberExpression | RegularExpression;\n}\n\nexport function createRegistry() {\n const _paramRegistry = new ParameterTypeRegistry();\n const _entries: Entry[] = [];\n\n for (const t of typeDefinitions) {\n _paramRegistry.defineParameterType(\n new ParameterType(t.name, t.regexp, null, t.transformer as any, t.useForSnippets),\n );\n }\n\n return {\n /** IStepRegistry-compatible defs (source = String(expression), no raw expr). */\n get defs() {\n return _entries.map(({ type, expression, fn, comment }) => ({\n type,\n source: String(expression),\n fn,\n comment,\n }));\n },\n\n /** Raw step definitions with original expression — used by define.ts for Cucumber registration. */\n get definitions(): StepDefinition[] {\n return _entries.map(({ type, expression, fn, comment }) => ({ type, expression, fn, comment }));\n },\n\n defineStep(type: StepType, expression: string | RegExp, fn: StepHandler, comment?: string): void {\n const source = String(expression);\n const duplicate = _entries.some((entry) => entry.type === type && String(entry.expression) === source);\n if (duplicate) return;\n\n const expr =\n typeof expression === 'string'\n ? new CucumberExpression(sanitizeStepDefinition(expression), _paramRegistry)\n : new RegularExpression(expression, _paramRegistry);\n _entries.push({ type, expression, fn, comment, expr });\n },\n\n defineParameterType(type: ParameterTypeDefinition<unknown>): void {\n _paramRegistry.defineParameterType(\n new ParameterType(type.name, type.regexp, null, type.transformer, type.useForSnippets),\n );\n },\n\n match(text: string) {\n for (const entry of _entries) {\n const args = entry.expr.match(text);\n if (args) {\n return {\n def: { type: entry.type, source: String(entry.expression), fn: entry.fn, comment: entry.comment },\n values: args.map((a) => a.getValue(null)),\n args,\n };\n }\n }\n return null;\n },\n };\n}\n\nconst REGISTRY_KEY = Symbol.for('letsrunit.bdd.registry');\ntype GlobalRegistryStore = typeof globalThis & {\n [REGISTRY_KEY]?: ReturnType<typeof createRegistry>;\n};\n\nconst registryStore = globalThis as GlobalRegistryStore;\nexport const registry = registryStore[REGISTRY_KEY] ?? (registryStore[REGISTRY_KEY] = createRegistry());\n\nexport function Given(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n const def: StepDefinition = { type: 'Given', expression, fn, comment };\n registry.defineStep('Given', expression, fn, comment);\n return def;\n}\n\nexport function When(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n const def: StepDefinition = { type: 'When', expression, fn, comment };\n registry.defineStep('When', expression, fn, comment);\n return def;\n}\n\nexport function Then(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n const def: StepDefinition = { type: 'Then', expression, fn, comment };\n registry.defineStep('Then', expression, fn, comment);\n return def;\n}\n","import { expect, type Expect } from '@playwright/test';\n\nexport function expectOrNot<T>(\n actual: T,\n toBe: boolean\n): ReturnType<Expect<T>> | ReturnType<ReturnType<Expect<T>>['not']> {\n return toBe ? expect(actual) : expect(actual).not;\n}\n","import { fuzzyLocator } from '@letsrunit/playwright';\nimport { Then } from '../registry';\nimport { expectOrNot } from '../utils/test-helpers';\n\nconst WAIT_TIMEOUT = 5000;\n\nexport const see = Then(\n 'the page {contains|does not contain} {locator}',\n async function (visible: boolean, selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n await expectOrNot(el, visible).toBeVisible({ timeout: WAIT_TIMEOUT });\n },\n);\n\nexport const contain = Then(\n '{locator} {contains|does not contain} {locator}',\n async function (selector: string, contain: boolean, child: string) {\n const el = await fuzzyLocator(this.page, selector);\n const childElement = el.locator(child);\n await expectOrNot(childElement, contain).toBeAttached({ timeout: WAIT_TIMEOUT });\n },\n);\n","import type { Snapshot } from '@letsrunit/playwright';\nimport { Page } from '@playwright/test';\nimport ISO6391 from 'iso-639-1';\nimport metascraper from 'metascraper';\nimport metascraperLang from 'metascraper-lang';\n\nconst scrapeLang = metascraper([metascraperLang()]);\n\nexport async function getLang(\n page: Pick<Page, 'content' | 'url'> | Snapshot,\n): Promise<{ code: string; name: string} | null> {\n const html = 'html' in page ? page.html : await page.content();\n const url = typeof page.url === 'function' ? page.url() : page.url;\n\n const { lang = null } = await scrapeLang({ html, url });\n if (!lang) return null;\n\n const code = lang.substring(0, 2);\n const name = ISO6391.getName(code) || code;\n\n return { code, name };\n}\n","import { suppressInterferences, waitForIdle } from '@letsrunit/playwright';\nimport { eventually, pathRegexp, splitUrl } from '@letsrunit/utils';\nimport { expect } from '@playwright/test';\nimport { World } from '../types';\nimport { getLang } from '../utils/get-lang';\nimport { Given, Then, When } from '../registry';\n\nasync function openPage(world: World, path: string): Promise<void> {\n const { page } = world;\n\n const result = await page.goto(path);\n expect(result?.status()).toBeLessThan(400);\n\n await waitForIdle(page);\n\n world.lang ??= (await getLang(page)) || undefined;\n}\n\nexport const navHome = Given(\"I'm on the homepage\", async function () {\n await openPage(this, '/');\n});\n\nexport const navPath = Given(\"I'm on page {string}\", async function (path: string) {\n await openPage(this, path);\n});\n\nexport const popupClosed = Given('all popups are closed', async function (){\n await suppressInterferences(this.page, { lang: this.lang?.code });\n});\n\nexport const assertPath = Then('I should be on page {string}', async function (expectedPath: string) {\n await eventually(async () => {\n const { path: actualPath } = splitUrl(this.page.url());\n\n if (expectedPath.includes(':')) {\n const { regexp, names } = pathRegexp(expectedPath);\n\n expect(actualPath, `Expected path ${actualPath} to match pattern ${expectedPath}`).toMatch(regexp);\n\n const match = actualPath.match(regexp);\n this.pathParams = Object.fromEntries(names.map((name, i) => [name, decodeURIComponent(match![i + 1])]));\n } else {\n expect(actualPath).toEqual(expectedPath);\n delete this.pathParams;\n }\n });\n});\n\nexport const back = When('I go back to the previous page', async function () {\n await this.page.goBack();\n await waitForIdle(this.page);\n});\n","import type { KeyCombo } from '@letsrunit/gherkin';\nimport { fuzzyLocator, waitAfterInteraction } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from '../registry';\n\nconst TIMEOUT = 2500;\n\ntype MouseAction = 'click' | 'double-click' | 'right-click' | 'hover';\n\nasync function press(el: Locator, action: MouseAction) {\n if (action === 'hover') {\n await el.hover({ timeout: TIMEOUT });\n } else {\n await el.click({\n button: action === 'right-click' ? 'right' : 'left',\n clickCount: action === 'double-click' ? 2 : 1,\n timeout: TIMEOUT,\n });\n }\n}\n\nexport const click = When(\n 'I {click|double-click|right-click|hover} {locator}',\n async function (action: MouseAction, selector: string) {\n const prevUrl = this.page.url();\n\n const el = await fuzzyLocator(this.page, selector);\n await press(el, action);\n\n await waitAfterInteraction(this.page, el, { prevUrl });\n },\n);\n\nexport const clickHold = When(\n 'I {click|double-click|right-click|hover} {locator} while holding {keys}',\n async function (action: MouseAction, selector: string, combo: KeyCombo) {\n const prevUrl = this.page.url();\n\n const el = await fuzzyLocator(this.page, selector);\n const keys = [...combo.modifiers, combo.key];\n\n for (const m of keys) await this.page.keyboard.down(m);\n await press(el, action);\n for (const m of keys.reverse()) await this.page.keyboard.up(m);\n\n await waitAfterInteraction(this.page, el, { prevUrl });\n },\n);\n\nexport const scroll = When('I scroll {locator} into view', async function (selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n await el.scrollIntoViewIfNeeded({ timeout: TIMEOUT });\n});\n","import { fuzzyLocator, setFieldValue } from '@letsrunit/playwright';\nimport { type Scalar, sleep } from '@letsrunit/utils';\nimport { When } from '../registry';\n\nconst TIMEOUT = 500;\nconst DELAY = 500;\n\nexport const set = When('I set {locator} to {value}', async function (selector: string, value: Scalar | Scalar[]) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, value, { timeout: TIMEOUT });\n await sleep(DELAY);\n});\n\nexport const setRange = When(\n 'I set {locator} to range of {value} to {value}',\n async function (selector: string, from: Scalar, to: Scalar) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, { from, to }, { timeout: TIMEOUT });\n await sleep(DELAY);\n },\n);\n\nexport const clear = When('I clear {locator}', async function (selector) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, null, { timeout: TIMEOUT });\n await sleep(DELAY);\n});\n\nexport const check = When(\n 'I {check|uncheck} {locator}',\n async function (check: boolean, selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n await setFieldValue(el, check, { timeout: TIMEOUT });\n await sleep(DELAY);\n },\n 'For checkbox input or switch component',\n);\n\nexport const focus = When('I {focus|blur} {locator}', async function (focus: boolean, selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n\n if (focus) {\n await el.focus({ timeout: TIMEOUT });\n } else {\n await el.blur({ timeout: TIMEOUT });\n }\n});\n","import type { KeyCombo } from '@letsrunit/gherkin';\nimport { sleep } from '@letsrunit/utils';\nimport { When } from '../registry';\n\nconst DELAY = 500;\n\nexport const press = When('I press {keys}', async function (combo: KeyCombo) {\n // Hold modifiers\n for (const m of combo.modifiers) await this.page.keyboard.down(m);\n\n // Press final key\n await this.page.keyboard.press(combo.key);\n\n // Release modifiers (reverse order)\n for (const m of combo.modifiers.toReversed()) await this.page.keyboard.up(m);\n\n await sleep(DELAY);\n});\n\nexport const type = When('I type {string}', async function (value: string) {\n await this.page.keyboard.type(value, { delay: 200 });\n await sleep(DELAY);\n});\n","import { receiveMail, toEml } from '@letsrunit/mailbox';\nimport { asFilename, textToHtml } from '@letsrunit/utils';\nimport { Given, Then } from '../registry';\n\nconst MAX_RECEIVE_WAIT = 120_000; // 2 minutes\n\nexport const view = Given(\n `I'm viewing an email sent to {string} with subject {string}`,\n async function (address: string, subject: string) {\n const emails = await receiveMail(address, { full: true, after: this.startTime, subject, limit: 1 });\n if (emails.length === 0) {\n throw new Error(`Did not receive an email with subject \"${subject}\"`);\n }\n\n const email = emails[0];\n\n await this.page.goto('about:blank', { waitUntil: 'load' });\n await this.page.setContent(email.html ?? textToHtml(email.text!), { waitUntil: 'domcontentloaded' });\n },\n);\n\nexport const receive = Then(\n 'I received an email sent to {string} with subject {string}',\n async function (address: string, subject: string) {\n const emails = await receiveMail(address, {\n after: this.startTime,\n full: true,\n subject,\n wait: true,\n timeout: MAX_RECEIVE_WAIT,\n limit: 1,\n });\n\n if (emails.length === 0) {\n throw new Error(`Did not receive an email with subject \"${subject}\"`);\n }\n\n const email = emails[0];\n\n this.attach(toEml(email), {\n mediaType: 'message/rfc822',\n fileName: asFilename(email.subject, 'eml'),\n });\n },\n);\n","import { fuzzyLocator } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from '../registry';\n\nconst TIMEOUT = 500;\n\nasync function copyInput(el: Locator): Promise<string | undefined> {\n try {\n return await el.inputValue();\n } catch {}\n}\n\nasync function copyLink(el: Locator): Promise<string | undefined> {\n try {\n const tag = await el.evaluate<string>((n: Element) => n.tagName.toLowerCase());\n const href = tag === 'a' ? await el.getAttribute('href') : null;\n if (href) {\n return href.startsWith('mailto:') ? href.replace(/^mailto:/i, '') : href;\n }\n } catch {}\n}\n\nasync function copyText(el: Locator): Promise<string | null> {\n return (await el.textContent()) ?? null;\n}\n\nexport const copy = When('I copy {locator} to the clipboard', async function (selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n let value = (await copyInput(el)) ?? (await copyLink(el)) ?? (await copyText(el));\n\n this.clipboard = { value };\n});\n\nexport const paste = When('I paste from the clipboard into {locator}', async function (selector: string) {\n const el = await fuzzyLocator(this.page, selector);\n const value = this.clipboard?.value || '';\n\n await el.fill(String(value), { timeout: TIMEOUT });\n});\n","import type { Readable } from 'node:stream';\n\ntype AttachData = string | Buffer | Readable;\ntype AttachOptions = string | {\n mediaType: string;\n fileName?: string;\n};\n\nexport function toFile(data: AttachData, options?: AttachOptions): File {\n const opt =\n typeof options === 'string'\n ? { mediaType: options }\n : options ?? { mediaType: 'application/octet-stream' };\n\n const type = opt.mediaType || 'application/octet-stream';\n const name = opt.fileName || `attachment-${Date.now()}`;\n\n if (isReadable(data)) {\n throw new Error('toFile does not support Readable streams; provide Buffer or string');\n }\n\n const part = typeof data === 'string' ? data : new Uint8Array(data);\n\n return new File([part], name, { type });\n}\n\nfunction isReadable(value: unknown): value is Readable {\n return (\n !!value &&\n typeof value === 'object' &&\n (typeof (value as any).pipe === 'function' || typeof (value as any).read === 'function')\n );\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letsrunit/bdd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "BDD step definitions for browser automation with letsrunit",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"testing",
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"packageManager": "yarn@4.10.3",
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@cucumber/cucumber-expressions": "^18.1.0",
|
|
48
|
-
"@letsrunit/gherkin": "0.
|
|
49
|
-
"@letsrunit/mailbox": "0.
|
|
50
|
-
"@letsrunit/playwright": "0.
|
|
51
|
-
"@letsrunit/utils": "0.
|
|
48
|
+
"@letsrunit/gherkin": "0.11.0",
|
|
49
|
+
"@letsrunit/mailbox": "0.11.0",
|
|
50
|
+
"@letsrunit/playwright": "0.11.0",
|
|
51
|
+
"@letsrunit/utils": "0.11.0",
|
|
52
52
|
"@playwright/test": "^1.57.0",
|
|
53
53
|
"iso-639-1": "^3.1.5",
|
|
54
54
|
"metascraper": "^5.49.15",
|
package/src/registry.ts
CHANGED
|
@@ -43,6 +43,10 @@ export function createRegistry() {
|
|
|
43
43
|
},
|
|
44
44
|
|
|
45
45
|
defineStep(type: StepType, expression: string | RegExp, fn: StepHandler, comment?: string): void {
|
|
46
|
+
const source = String(expression);
|
|
47
|
+
const duplicate = _entries.some((entry) => entry.type === type && String(entry.expression) === source);
|
|
48
|
+
if (duplicate) return;
|
|
49
|
+
|
|
46
50
|
const expr =
|
|
47
51
|
typeof expression === 'string'
|
|
48
52
|
? new CucumberExpression(sanitizeStepDefinition(expression), _paramRegistry)
|
|
@@ -72,7 +76,13 @@ export function createRegistry() {
|
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
const REGISTRY_KEY = Symbol.for('letsrunit.bdd.registry');
|
|
80
|
+
type GlobalRegistryStore = typeof globalThis & {
|
|
81
|
+
[REGISTRY_KEY]?: ReturnType<typeof createRegistry>;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const registryStore = globalThis as GlobalRegistryStore;
|
|
85
|
+
export const registry = registryStore[REGISTRY_KEY] ?? (registryStore[REGISTRY_KEY] = createRegistry());
|
|
76
86
|
|
|
77
87
|
export function Given(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {
|
|
78
88
|
const def: StepDefinition = { type: 'Given', expression, fn, comment };
|
package/src/steps/assert.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { expectOrNot } from '../utils/test-helpers';
|
|
|
5
5
|
const WAIT_TIMEOUT = 5000;
|
|
6
6
|
|
|
7
7
|
export const see = Then(
|
|
8
|
-
'
|
|
8
|
+
'the page {contains|does not contain} {locator}',
|
|
9
9
|
async function (visible: boolean, selector: string) {
|
|
10
10
|
const el = await fuzzyLocator(this.page, selector);
|
|
11
11
|
await expectOrNot(el, visible).toBeVisible({ timeout: WAIT_TIMEOUT });
|