@letsrunit/bdd 0.3.8 → 0.3.9

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.
@@ -1,5 +1,5 @@
1
1
  import { locatorParameter, valueParameter, keysParameter, booleanParameter, enumParameter } from '@letsrunit/gherkin';
2
- import { locator, setFieldValue, waitAfterInteraction, suppressInterferences, waitForIdle } from '@letsrunit/playwright';
2
+ import { fuzzyLocator, setFieldValue, waitAfterInteraction, suppressInterferences, waitForIdle } from '@letsrunit/playwright';
3
3
  import { expect } from '@playwright/test';
4
4
  import { asFilename, eventually, splitUrl, pathRegexp, sleep, textToHtml } from '@letsrunit/utils';
5
5
  import { receiveMail, toEml } from '@letsrunit/mailbox';
@@ -51,14 +51,14 @@ var WAIT_TIMEOUT = 5e3;
51
51
  var see = Then(
52
52
  "The page {contains|not contains} {locator}",
53
53
  async function(visible, selector) {
54
- const el = await locator(this.page, selector);
54
+ const el = await fuzzyLocator(this.page, selector);
55
55
  await expectOrNot(el, visible).toBeVisible({ timeout: WAIT_TIMEOUT });
56
56
  }
57
57
  );
58
58
  var contain = Then(
59
59
  "{locator} {contains|not contains} {locator}",
60
60
  async function(selector, contain2, child) {
61
- const el = await locator(this.page, selector);
61
+ const el = await fuzzyLocator(this.page, selector);
62
62
  const childElement = el.locator(child);
63
63
  await expectOrNot(childElement, contain2).toBeAttached({ timeout: WAIT_TIMEOUT });
64
64
  }
@@ -91,12 +91,12 @@ async function copyText(el) {
91
91
  return await el.textContent() ?? null;
92
92
  }
93
93
  var copy = When("I copy {locator} to the clipboard", async function(selector) {
94
- const el = await locator(this.page, selector);
94
+ const el = await fuzzyLocator(this.page, selector);
95
95
  let value = await copyInput(el) ?? await copyLink(el) ?? await copyText(el);
96
96
  this.clipboard = { value };
97
97
  });
98
98
  var paste = When("I paste from the clipboard into {locator}", async function(selector) {
99
- const el = await locator(this.page, selector);
99
+ const el = await fuzzyLocator(this.page, selector);
100
100
  const value = this.clipboard?.value || "";
101
101
  await el.fill(String(value), { timeout: TIMEOUT });
102
102
  });
@@ -113,34 +113,34 @@ __export(form_exports, {
113
113
  var TIMEOUT2 = 500;
114
114
  var DELAY = 500;
115
115
  var set = When("I set {locator} to {value}", async function(selector, value) {
116
- const el = await locator(this.page, selector);
116
+ const el = await fuzzyLocator(this.page, selector);
117
117
  await setFieldValue(el, value, { timeout: TIMEOUT2 });
118
118
  await sleep(DELAY);
119
119
  });
120
120
  var setRange = When(
121
121
  "I set {locator} to range of {value} to {value}",
122
122
  async function(selector, from, to) {
123
- const el = await locator(this.page, selector);
123
+ const el = await fuzzyLocator(this.page, selector);
124
124
  await setFieldValue(el, { from, to }, { timeout: TIMEOUT2 });
125
125
  await sleep(DELAY);
126
126
  }
127
127
  );
128
128
  var clear = When("I clear {locator}", async function(selector) {
129
- const el = await locator(this.page, selector);
129
+ const el = await fuzzyLocator(this.page, selector);
130
130
  await setFieldValue(el, null, { timeout: TIMEOUT2 });
131
131
  await sleep(DELAY);
132
132
  });
133
133
  var check = When(
134
134
  "I {check|uncheck} {locator}",
135
135
  async function(check2, selector) {
136
- const el = await locator(this.page, selector);
136
+ const el = await fuzzyLocator(this.page, selector);
137
137
  await setFieldValue(el, check2, { timeout: TIMEOUT2 });
138
138
  await sleep(DELAY);
139
139
  },
140
140
  "For checkbox input or switch component"
141
141
  );
142
142
  var focus = When("I {focus|blur} {locator}", async function(focus2, selector) {
143
- const el = await locator(this.page, selector);
143
+ const el = await fuzzyLocator(this.page, selector);
144
144
  if (focus2) {
145
145
  await el.focus({ timeout: TIMEOUT2 });
146
146
  } else {
@@ -230,7 +230,7 @@ var click = When(
230
230
  "I {click|double-click|right-click|hover} {locator}",
231
231
  async function(action, selector) {
232
232
  const prevUrl = this.page.url();
233
- const el = await locator(this.page, selector);
233
+ const el = await fuzzyLocator(this.page, selector);
234
234
  await press2(el, action);
235
235
  await waitAfterInteraction(this.page, el, { prevUrl });
236
236
  }
@@ -239,7 +239,7 @@ var clickHold = When(
239
239
  "I {click|double-click|right-click|hover} {locator} while holding {keys}",
240
240
  async function(action, selector, combo) {
241
241
  const prevUrl = this.page.url();
242
- const el = await locator(this.page, selector);
242
+ const el = await fuzzyLocator(this.page, selector);
243
243
  const keys = [...combo.modifiers, combo.key];
244
244
  for (const m of keys) await this.page.keyboard.down(m);
245
245
  await press2(el, action);
@@ -248,7 +248,7 @@ var clickHold = When(
248
248
  }
249
249
  );
250
250
  var scroll = When("I scroll {locator} into view", async function(selector) {
251
- const el = await locator(this.page, selector);
251
+ const el = await fuzzyLocator(this.page, selector);
252
252
  await el.scrollIntoViewIfNeeded({ timeout: TIMEOUT3 });
253
253
  });
254
254
 
@@ -320,5 +320,5 @@ var stepsDefinitions = [
320
320
  ];
321
321
 
322
322
  export { stepsDefinitions, typeDefinitions };
323
- //# sourceMappingURL=chunk-YT56PTQF.js.map
324
- //# sourceMappingURL=chunk-YT56PTQF.js.map
323
+ //# sourceMappingURL=chunk-A7ZD72RB.js.map
324
+ //# sourceMappingURL=chunk-A7ZD72RB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/parameters.ts","../src/steps/assert.ts","../src/utils/test-helpers.ts","../src/steps/wrappers.ts","../src/steps/clipboard.ts","../src/steps/form.ts","../src/steps/keyboard.ts","../src/steps/mailbox.ts","../src/steps/mouse.ts","../src/steps/navigation.ts","../src/utils/get-lang.ts","../src/steps/index.ts"],"names":["contain","fuzzyLocator","TIMEOUT","check","focus","DELAY","sleep","press","expect"],"mappings":";;;;;;;;;;;;;;AAEO,IAAM,eAAA,GAAkB;AAAA,EAC7B,gBAAA,EAAiB;AAAA,EACjB,cAAA,EAAe;AAAA,EACf,aAAA,EAAc;AAAA,EAEd,gBAAA,CAAiB,WAAW,QAAQ,CAAA;AAAA,EACpC,gBAAA,CAAiB,SAAA,EAAW,UAAA,EAAY,mBAAmB,CAAA;AAAA,EAC3D,gBAAA,CAAiB,SAAA,EAAW,WAAA,EAAa,kBAAkB,CAAA;AAAA,EAC3D,gBAAA,CAAiB,UAAA,EAAY,cAAA,EAAgB,qBAAqB,CAAA;AAAA,EAElE,gBAAA,CAAiB,OAAA,EAAS,SAAA,EAAW,gBAAgB,CAAA;AAAA,EACrD,gBAAA,CAAiB,SAAS,MAAM,CAAA;AAAA,EAEhC,cAAc,CAAC,OAAA,EAAS,gBAAgB,aAAA,EAAe,OAAO,GAAG,kCAAkC;AACrG;;;AChBA,IAAA,cAAA,GAAA,EAAA;AAAA,QAAA,CAAA,cAAA,EAAA;AAAA,EAAA,OAAA,EAAA,MAAA,OAAA;AAAA,EAAA,GAAA,EAAA,MAAA;AAAA,CAAA,CAAA;ACEO,SAAS,WAAA,CACd,QACA,IAAA,EACkE;AAClE,EAAA,OAAO,OAAO,MAAA,CAAO,MAAM,CAAA,GAAI,MAAA,CAAO,MAAM,CAAA,CAAE,GAAA;AAChD;;;ACLO,SAAS,KAAA,CAAM,UAAA,EAA6B,EAAA,EAAiB,OAAA,EAAkC;AACpG,EAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,UAAA,EAAY,IAAI,OAAA,EAAQ;AAClD;AAEO,SAAS,IAAA,CAAK,UAAA,EAA6B,EAAA,EAAiB,OAAA,EAAkC;AACnG,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAA,EAAY,IAAI,OAAA,EAAQ;AACjD;AAEO,SAAS,IAAA,CAAK,UAAA,EAA6B,EAAA,EAAiB,OAAA,EAAkC;AACnG,EAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,UAAA,EAAY,IAAI,OAAA,EAAQ;AACjD;;;AFRA,IAAM,YAAA,GAAe,GAAA;AAEd,IAAM,GAAA,GAAM,IAAA;AAAA,EACjB,4CAAA;AAAA,EACA,eAAgB,SAAkB,QAAA,EAAkB;AAClD,IAAA,MAAM,EAAA,GAAK,MAAM,YAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,IAAA,MAAM,WAAA,CAAY,IAAI,OAAO,CAAA,CAAE,YAAY,EAAE,OAAA,EAAS,cAAc,CAAA;AAAA,EACtE;AACF,CAAA;AAEO,IAAM,OAAA,GAAU,IAAA;AAAA,EACrB,6CAAA;AAAA,EACA,eAAgB,QAAA,EAAkBA,QAAAA,EAAkB,KAAA,EAAe;AACjE,IAAA,MAAM,EAAA,GAAK,MAAM,YAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,IAAA,MAAM,YAAA,GAAe,EAAA,CAAG,OAAA,CAAQ,KAAK,CAAA;AACrC,IAAA,MAAM,WAAA,CAAY,cAAcA,QAAO,CAAA,CAAE,aAAa,EAAE,OAAA,EAAS,cAAc,CAAA;AAAA,EACjF;AACF,CAAA;;;AGrBA,IAAA,iBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,iBAAA,EAAA;AAAA,EAAA,IAAA,EAAA,MAAA,IAAA;AAAA,EAAA,KAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAIA,IAAM,OAAA,GAAU,GAAA;AAEhB,eAAe,UAAU,EAAA,EAA0C;AACjE,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,GAAG,UAAA,EAAW;AAAA,EAC7B,CAAA,CAAA,MAAQ;AAAA,EAAC;AACX;AAEA,eAAe,SAAS,EAAA,EAA0C;AAChE,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,EAAA,CAAG,QAAA,CAAiB,CAAC,CAAA,KAAe,CAAA,CAAE,OAAA,CAAQ,WAAA,EAAa,CAAA;AAC7E,IAAA,MAAM,OAAO,GAAA,KAAQ,GAAA,GAAM,MAAM,EAAA,CAAG,YAAA,CAAa,MAAM,CAAA,GAAI,IAAA;AAC3D,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,OAAO,IAAA,CAAK,WAAW,SAAS,CAAA,GAAI,KAAK,OAAA,CAAQ,WAAA,EAAa,EAAE,CAAA,GAAI,IAAA;AAAA,IACtE;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAAC;AACX;AAEA,eAAe,SAAS,EAAA,EAAqC;AAC3D,EAAA,OAAQ,MAAM,EAAA,CAAG,WAAA,EAAY,IAAM,IAAA;AACrC;AAEO,IAAM,IAAA,GAAO,IAAA,CAAK,mCAAA,EAAqC,eAAgB,QAAA,EAAkB;AAC9F,EAAA,MAAM,EAAA,GAAK,MAAMC,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,EAAA,IAAI,KAAA,GAAS,MAAM,SAAA,CAAU,EAAE,CAAA,IAAO,MAAM,QAAA,CAAS,EAAE,CAAA,IAAO,MAAM,QAAA,CAAS,EAAE,CAAA;AAE/E,EAAA,IAAA,CAAK,SAAA,GAAY,EAAE,KAAA,EAAM;AAC3B,CAAC,CAAA;AAEM,IAAM,KAAA,GAAQ,IAAA,CAAK,2CAAA,EAA6C,eAAgB,QAAA,EAAkB;AACvG,EAAA,MAAM,EAAA,GAAK,MAAMA,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,SAAA,EAAW,KAAA,IAAS,EAAA;AAEvC,EAAA,MAAM,EAAA,CAAG,KAAK,MAAA,CAAO,KAAK,GAAG,EAAE,OAAA,EAAS,SAAS,CAAA;AACnD,CAAC,CAAA;;;ACtCD,IAAA,YAAA,GAAA,EAAA;AAAA,QAAA,CAAA,YAAA,EAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,GAAA,EAAA,MAAA,GAAA;AAAA,EAAA,QAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAIA,IAAMC,QAAAA,GAAU,GAAA;AAChB,IAAM,KAAA,GAAQ,GAAA;AAEP,IAAM,GAAA,GAAM,IAAA,CAAK,4BAAA,EAA8B,eAAgB,UAAkB,KAAA,EAA0B;AAChH,EAAA,MAAM,EAAA,GAAK,MAAMD,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,EAAA,MAAM,cAAc,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAASC,UAAS,CAAA;AACnD,EAAA,MAAM,MAAM,KAAK,CAAA;AACnB,CAAC,CAAA;AAEM,IAAM,QAAA,GAAW,IAAA;AAAA,EACtB,gDAAA;AAAA,EACA,eAAgB,QAAA,EAAkB,IAAA,EAAc,EAAA,EAAY;AAC1D,IAAA,MAAM,EAAA,GAAK,MAAMD,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,IAAA,MAAM,aAAA,CAAc,IAAI,EAAE,IAAA,EAAM,IAAG,EAAG,EAAE,OAAA,EAASC,QAAAA,EAAS,CAAA;AAC1D,IAAA,MAAM,MAAM,KAAK,CAAA;AAAA,EACnB;AACF,CAAA;AAEO,IAAM,KAAA,GAAQ,IAAA,CAAK,mBAAA,EAAqB,eAAgB,QAAA,EAAU;AACvE,EAAA,MAAM,EAAA,GAAK,MAAMD,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,EAAA,MAAM,cAAc,EAAA,EAAI,IAAA,EAAM,EAAE,OAAA,EAASC,UAAS,CAAA;AAClD,EAAA,MAAM,MAAM,KAAK,CAAA;AACnB,CAAC,CAAA;AAEM,IAAM,KAAA,GAAQ,IAAA;AAAA,EACnB,6BAAA;AAAA,EACA,eAAgBC,QAAgB,QAAA,EAAkB;AAChD,IAAA,MAAM,EAAA,GAAK,MAAMF,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,IAAA,MAAM,cAAc,EAAA,EAAIE,MAAAA,EAAO,EAAE,OAAA,EAASD,UAAS,CAAA;AACnD,IAAA,MAAM,MAAM,KAAK,CAAA;AAAA,EACnB,CAAA;AAAA,EACA;AACF,CAAA;AAEO,IAAM,KAAA,GAAQ,IAAA,CAAK,0BAAA,EAA4B,eAAgBE,QAAgB,QAAA,EAAkB;AACtG,EAAA,MAAM,EAAA,GAAK,MAAMH,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AAEjD,EAAA,IAAIG,MAAAA,EAAO;AACT,IAAA,MAAM,EAAA,CAAG,KAAA,CAAM,EAAE,OAAA,EAASF,UAAS,CAAA;AAAA,EACrC,CAAA,MAAO;AACL,IAAA,MAAM,EAAA,CAAG,IAAA,CAAK,EAAE,OAAA,EAASA,UAAS,CAAA;AAAA,EACpC;AACF,CAAC,CAAA;;;AC9CD,IAAA,gBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,gBAAA,EAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,IAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAIA,IAAMG,MAAAA,GAAQ,GAAA;AAEP,IAAM,KAAA,GAAQ,IAAA,CAAK,gBAAA,EAAkB,eAAgB,KAAA,EAAiB;AAE3E,EAAA,KAAA,MAAW,CAAA,IAAK,MAAM,SAAA,EAAW,MAAM,KAAK,IAAA,CAAK,QAAA,CAAS,KAAK,CAAC,CAAA;AAGhE,EAAA,MAAM,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,MAAM,GAAG,CAAA;AAGxC,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,CAAM,SAAA,CAAU,UAAA,EAAW,QAAS,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,CAAC,CAAA;AAE3E,EAAA,MAAMC,MAAMD,MAAK,CAAA;AACnB,CAAC,CAAA;AAEM,IAAM,IAAA,GAAO,IAAA,CAAK,iBAAA,EAAmB,eAAgB,KAAA,EAAe;AACzE,EAAA,MAAM,IAAA,CAAK,KAAK,QAAA,CAAS,IAAA,CAAK,OAAO,EAAE,KAAA,EAAO,KAAK,CAAA;AACnD,EAAA,MAAMC,MAAMD,MAAK,CAAA;AACnB,CAAC,CAAA;;;ACtBD,IAAA,eAAA,GAAA,EAAA;AAAA,QAAA,CAAA,eAAA,EAAA;AAAA,EAAA,OAAA,EAAA,MAAA,OAAA;AAAA,EAAA,IAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAIA,IAAM,gBAAA,GAAmB,IAAA;AAElB,IAAM,IAAA,GAAO,KAAA;AAAA,EAClB,CAAA,2DAAA,CAAA;AAAA,EACA,eAAgB,SAAiB,OAAA,EAAiB;AAChD,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,OAAA,EAAS,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,IAAA,CAAK,SAAA,EAAW,OAAA,EAAS,KAAA,EAAO,GAAG,CAAA;AAClG,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uCAAA,EAA0C,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,IACtE;AAEA,IAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AAEtB,IAAA,MAAM,KAAK,IAAA,CAAK,IAAA,CAAK,eAAe,EAAE,SAAA,EAAW,QAAQ,CAAA;AACzD,IAAA,MAAM,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,KAAA,CAAM,IAAA,IAAQ,UAAA,CAAW,KAAA,CAAM,IAAK,CAAA,EAAG,EAAE,SAAA,EAAW,kBAAA,EAAoB,CAAA;AAAA,EACrG;AACF,CAAA;AAEO,IAAM,OAAA,GAAU,IAAA;AAAA,EACrB,4DAAA;AAAA,EACA,eAAgB,SAAiB,OAAA,EAAiB;AAChD,IAAA,MAAM,MAAA,GAAS,MAAM,WAAA,CAAY,OAAA,EAAS;AAAA,MACxC,OAAO,IAAA,CAAK,SAAA;AAAA,MACZ,IAAA,EAAM,IAAA;AAAA,MACN,OAAA;AAAA,MACA,IAAA,EAAM,IAAA;AAAA,MACN,OAAA,EAAS,gBAAA;AAAA,MACT,KAAA,EAAO;AAAA,KACR,CAAA;AAED,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uCAAA,EAA0C,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,IACtE;AAEA,IAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AAEtB,IAAA,IAAA,CAAK,MAAA,CAAO,KAAA,CAAM,KAAK,CAAA,EAAG;AAAA,MACxB,SAAA,EAAW,gBAAA;AAAA,MACX,QAAA,EAAU,UAAA,CAAW,KAAA,CAAM,OAAA,EAAS,KAAK;AAAA,KAC1C,CAAA;AAAA,EACH;AACF,CAAA;;;AC5CA,IAAA,aAAA,GAAA,EAAA;AAAA,QAAA,CAAA,aAAA,EAAA;AAAA,EAAA,KAAA,EAAA,MAAA,KAAA;AAAA,EAAA,SAAA,EAAA,MAAA,SAAA;AAAA,EAAA,MAAA,EAAA,MAAA;AAAA,CAAA,CAAA;AAKA,IAAMH,QAAAA,GAAU,IAAA;AAIhB,eAAeK,MAAAA,CAAM,IAAa,MAAA,EAAqB;AACrD,EAAA,IAAI,WAAW,OAAA,EAAS;AACtB,IAAA,MAAM,EAAA,CAAG,KAAA,CAAM,EAAE,OAAA,EAASL,UAAS,CAAA;AAAA,EACrC,CAAA,MAAO;AACL,IAAA,MAAM,GAAG,KAAA,CAAM;AAAA,MACb,MAAA,EAAQ,MAAA,KAAW,aAAA,GAAgB,OAAA,GAAU,MAAA;AAAA,MAC7C,UAAA,EAAY,MAAA,KAAW,cAAA,GAAiB,CAAA,GAAI,CAAA;AAAA,MAC5C,OAAA,EAASA;AAAA,KACV,CAAA;AAAA,EACH;AACF;AAEO,IAAM,KAAA,GAAQ,IAAA;AAAA,EACnB,oDAAA;AAAA,EACA,eAAgB,QAAqB,QAAA,EAAkB;AACrD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,GAAA,EAAI;AAE9B,IAAA,MAAM,EAAA,GAAK,MAAMD,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,IAAA,MAAMM,MAAAA,CAAM,IAAI,MAAM,CAAA;AAEtB,IAAA,MAAM,qBAAqB,IAAA,CAAK,IAAA,EAAM,EAAA,EAAI,EAAE,SAAS,CAAA;AAAA,EACvD;AACF,CAAA;AAEO,IAAM,SAAA,GAAY,IAAA;AAAA,EACvB,yEAAA;AAAA,EACA,eAAgB,MAAA,EAAqB,QAAA,EAAkB,KAAA,EAAiB;AACtE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,GAAA,EAAI;AAE9B,IAAA,MAAM,EAAA,GAAK,MAAMN,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,IAAA,MAAM,OAAO,CAAC,GAAG,KAAA,CAAM,SAAA,EAAW,MAAM,GAAG,CAAA;AAE3C,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM,MAAM,KAAK,IAAA,CAAK,QAAA,CAAS,KAAK,CAAC,CAAA;AACrD,IAAA,MAAMM,MAAAA,CAAM,IAAI,MAAM,CAAA;AACtB,IAAA,KAAA,MAAW,CAAA,IAAK,KAAK,OAAA,EAAQ,QAAS,IAAA,CAAK,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,CAAC,CAAA;AAE7D,IAAA,MAAM,qBAAqB,IAAA,CAAK,IAAA,EAAM,EAAA,EAAI,EAAE,SAAS,CAAA;AAAA,EACvD;AACF,CAAA;AAEO,IAAM,MAAA,GAAS,IAAA,CAAK,8BAAA,EAAgC,eAAgB,QAAA,EAAkB;AAC3F,EAAA,MAAM,EAAA,GAAK,MAAMN,YAAAA,CAAa,IAAA,CAAK,MAAM,QAAQ,CAAA;AACjD,EAAA,MAAM,EAAA,CAAG,sBAAA,CAAuB,EAAE,OAAA,EAASC,UAAS,CAAA;AACtD,CAAC,CAAA;;;ACpDD,IAAA,kBAAA,GAAA,EAAA;AAAA,QAAA,CAAA,kBAAA,EAAA;AAAA,EAAA,UAAA,EAAA,MAAA,UAAA;AAAA,EAAA,IAAA,EAAA,MAAA,IAAA;AAAA,EAAA,OAAA,EAAA,MAAA,OAAA;AAAA,EAAA,OAAA,EAAA,MAAA,OAAA;AAAA,EAAA,WAAA,EAAA,MAAA;AAAA,CAAA,CAAA;ACMA,IAAM,UAAA,GAAa,WAAA,CAAY,CAAC,eAAA,EAAiB,CAAC,CAAA;AAElD,eAAsB,QACpB,IAAA,EAC+C;AAC/C,EAAA,MAAM,OAAO,MAAA,IAAU,IAAA,GAAO,KAAK,IAAA,GAAO,MAAM,KAAK,OAAA,EAAQ;AAC7D,EAAA,MAAM,GAAA,GAAM,OAAO,IAAA,CAAK,GAAA,KAAQ,aAAa,IAAA,CAAK,GAAA,KAAQ,IAAA,CAAK,GAAA;AAE/D,EAAA,MAAM,EAAE,OAAO,IAAA,EAAK,GAAI,MAAM,UAAA,CAAW,EAAE,IAAA,EAAM,GAAA,EAAK,CAAA;AACtD,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAElB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AAChC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA,IAAK,IAAA;AAEtC,EAAA,OAAO,EAAE,MAAM,IAAA,EAAK;AACtB;;;ADdA,eAAe,QAAA,CAAS,OAAc,IAAA,EAA6B;AACjE,EAAA,MAAM,EAAE,MAAK,GAAI,KAAA;AAEjB,EAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AACnC,EAAAM,OAAO,MAAA,EAAQ,MAAA,EAAQ,CAAA,CAAE,aAAa,GAAG,CAAA;AAEzC,EAAA,MAAM,YAAY,IAAI,CAAA;AAEtB,EAAA,KAAA,CAAM,IAAA,KAAU,MAAM,OAAA,CAAQ,IAAI,CAAA,IAAM,MAAA;AAC1C;AAEO,IAAM,OAAA,GAAU,KAAA,CAAM,qBAAA,EAAuB,iBAAkB;AACpE,EAAA,MAAM,QAAA,CAAS,MAAM,GAAG,CAAA;AAC1B,CAAC,CAAA;AAEM,IAAM,OAAA,GAAU,KAAA,CAAM,sBAAA,EAAwB,eAAgB,IAAA,EAAc;AACjF,EAAA,MAAM,QAAA,CAAS,MAAM,IAAI,CAAA;AAC3B,CAAC,CAAA;AAEM,IAAM,WAAA,GAAc,KAAA,CAAM,uBAAA,EAAyB,iBAAiB;AACzE,EAAA,MAAM,qBAAA,CAAsB,KAAK,IAAA,EAAM,EAAE,MAAM,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAClE,CAAC,CAAA;AAEM,IAAM,UAAA,GAAa,IAAA,CAAK,8BAAA,EAAgC,eAAgB,YAAA,EAAsB;AACnG,EAAA,MAAM,WAAW,YAAY;AAC3B,IAAA,MAAM,EAAE,MAAM,UAAA,EAAW,GAAI,SAAS,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA;AAErD,IAAA,IAAI,YAAA,CAAa,QAAA,CAAS,GAAG,CAAA,EAAG;AAC9B,MAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAM,GAAI,WAAW,YAAY,CAAA;AAEjD,MAAAA,MAAAA,CAAO,YAAY,CAAA,cAAA,EAAiB,UAAU,qBAAqB,YAAY,CAAA,CAAE,CAAA,CAAE,OAAA,CAAQ,MAAM,CAAA;AAEjG,MAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,MAAM,CAAA;AACrC,MAAA,IAAA,CAAK,aAAa,MAAA,CAAO,WAAA,CAAY,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM,CAAC,IAAA,EAAM,mBAAmB,KAAA,CAAO,CAAA,GAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAAA,IACxG,CAAA,MAAO;AACL,MAAAA,MAAAA,CAAO,UAAU,CAAA,CAAE,OAAA,CAAQ,YAAY,CAAA;AACvC,MAAA,OAAO,IAAA,CAAK,UAAA;AAAA,IACd;AAAA,EACF,CAAC,CAAA;AACH,CAAC,CAAA;AAEM,IAAM,IAAA,GAAO,IAAA,CAAK,gCAAA,EAAkC,iBAAkB;AAC3E,EAAA,MAAM,IAAA,CAAK,KAAK,MAAA,EAAO;AACvB,EAAA,MAAM,WAAA,CAAY,KAAK,IAAI,CAAA;AAC7B,CAAC,CAAA;;;AEzCM,IAAM,gBAAA,GAAqC;AAAA,EAChD,GAAG,MAAA,CAAO,MAAA,CAAO,cAAM,CAAA;AAAA,EACvB,GAAG,MAAA,CAAO,MAAA,CAAO,kBAAU,CAAA;AAAA,EAC3B,GAAG,MAAA,CAAO,MAAA,CAAO,aAAK,CAAA;AAAA,EACtB,GAAG,MAAA,CAAO,MAAA,CAAO,YAAI,CAAA;AAAA,EACrB,GAAG,MAAA,CAAO,MAAA,CAAO,gBAAQ,CAAA;AAAA,EACzB,GAAG,MAAA,CAAO,MAAA,CAAO,eAAO,CAAA;AAAA,EACxB,GAAG,MAAA,CAAO,MAAA,CAAO,iBAAS;AAC5B","file":"chunk-A7ZD72RB.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', 'not contains', /((?:not )?contains)/),\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];\n","import { fuzzyLocator } from '@letsrunit/playwright';\nimport { expectOrNot } from '../utils/test-helpers';\nimport { Then } from './wrappers';\n\nconst WAIT_TIMEOUT = 5000;\n\nexport const see = Then(\n 'The page {contains|not contains} {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|not contains} {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 { 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 type { StepDefinition, StepHandler } from '../types';\n\nexport function Given(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n return { type: 'Given', expression, fn, comment };\n}\n\nexport function When(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n return { type: 'When', expression, fn, comment };\n}\n\nexport function Then(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n return { type: 'Then', expression, fn, comment };\n}\n","import { fuzzyLocator } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from './wrappers';\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 { fuzzyLocator, setFieldValue } from '@letsrunit/playwright';\nimport { type Scalar, sleep } from '@letsrunit/utils';\nimport { When } from './wrappers';\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 './wrappers';\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 './wrappers';\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 type { KeyCombo } from '@letsrunit/gherkin';\nimport { fuzzyLocator, waitAfterInteraction } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from './wrappers';\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 { 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 './wrappers';\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 { 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 type { StepDefinition } from '../types';\nimport * as assert from './assert';\nimport * as clipboard from './clipboard';\nimport * as form from './form';\nimport * as keyboard from './keyboard';\nimport * as mailbox from './mailbox';\nimport * as mouse from './mouse';\nimport * as navigation from './navigation';\n\n// The order matters for the LLM\nexport const stepsDefinitions: StepDefinition[] = [\n ...Object.values(assert),\n ...Object.values(navigation),\n ...Object.values(mouse),\n ...Object.values(form),\n ...Object.values(keyboard),\n ...Object.values(mailbox),\n ...Object.values(clipboard),\n];\n"]}
package/dist/define.js CHANGED
@@ -1,4 +1,4 @@
1
- import { typeDefinitions, stepsDefinitions } from './chunk-YT56PTQF.js';
1
+ import { typeDefinitions, stepsDefinitions } from './chunk-A7ZD72RB.js';
2
2
  import { defineParameterType, Given, When, Then, BeforeAll, Before, After } from '@cucumber/cucumber';
3
3
  import { createFieldEngine, createDateEngine, browse } from '@letsrunit/playwright';
4
4
  import { selectors, chromium } from '@playwright/test';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { stepsDefinitions, typeDefinitions } from './chunk-YT56PTQF.js';
1
+ export { stepsDefinitions, typeDefinitions } from './chunk-A7ZD72RB.js';
2
2
 
3
3
  // src/utils/file.ts
4
4
  function toFile(data, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letsrunit/bdd",
3
- "version": "0.3.8",
3
+ "version": "0.3.9",
4
4
  "description": "BDD step definitions for browser automation with letsrunit",
5
5
  "keywords": [
6
6
  "testing",
@@ -52,10 +52,10 @@
52
52
  "packageManager": "yarn@4.10.3",
53
53
  "dependencies": {
54
54
  "@cucumber/cucumber-expressions": "^18.1.0",
55
- "@letsrunit/gherkin": "0.3.8",
56
- "@letsrunit/mailbox": "0.3.8",
57
- "@letsrunit/playwright": "0.3.8",
58
- "@letsrunit/utils": "0.3.8",
55
+ "@letsrunit/gherkin": "0.3.9",
56
+ "@letsrunit/mailbox": "0.3.9",
57
+ "@letsrunit/playwright": "0.3.9",
58
+ "@letsrunit/utils": "0.3.9",
59
59
  "@playwright/test": "^1.57.0",
60
60
  "iso-639-1": "^3.1.5",
61
61
  "metascraper": "^5.49.15",
@@ -1,4 +1,4 @@
1
- import { locator } from '@letsrunit/playwright';
1
+ import { fuzzyLocator } from '@letsrunit/playwright';
2
2
  import { expectOrNot } from '../utils/test-helpers';
3
3
  import { Then } from './wrappers';
4
4
 
@@ -7,7 +7,7 @@ const WAIT_TIMEOUT = 5000;
7
7
  export const see = Then(
8
8
  'The page {contains|not contains} {locator}',
9
9
  async function (visible: boolean, selector: string) {
10
- const el = await locator(this.page, selector);
10
+ const el = await fuzzyLocator(this.page, selector);
11
11
  await expectOrNot(el, visible).toBeVisible({ timeout: WAIT_TIMEOUT });
12
12
  },
13
13
  );
@@ -15,7 +15,7 @@ export const see = Then(
15
15
  export const contain = Then(
16
16
  '{locator} {contains|not contains} {locator}',
17
17
  async function (selector: string, contain: boolean, child: string) {
18
- const el = await locator(this.page, selector);
18
+ const el = await fuzzyLocator(this.page, selector);
19
19
  const childElement = el.locator(child);
20
20
  await expectOrNot(childElement, contain).toBeAttached({ timeout: WAIT_TIMEOUT });
21
21
  },
@@ -1,4 +1,4 @@
1
- import { locator } from '@letsrunit/playwright';
1
+ import { fuzzyLocator } from '@letsrunit/playwright';
2
2
  import type { Locator } from '@playwright/test';
3
3
  import { When } from './wrappers';
4
4
 
@@ -25,14 +25,14 @@ async function copyText(el: Locator): Promise<string | null> {
25
25
  }
26
26
 
27
27
  export const copy = When('I copy {locator} to the clipboard', async function (selector: string) {
28
- const el = await locator(this.page, selector);
28
+ const el = await fuzzyLocator(this.page, selector);
29
29
  let value = (await copyInput(el)) ?? (await copyLink(el)) ?? (await copyText(el));
30
30
 
31
31
  this.clipboard = { value };
32
32
  });
33
33
 
34
34
  export const paste = When('I paste from the clipboard into {locator}', async function (selector: string) {
35
- const el = await locator(this.page, selector);
35
+ const el = await fuzzyLocator(this.page, selector);
36
36
  const value = this.clipboard?.value || '';
37
37
 
38
38
  await el.fill(String(value), { timeout: TIMEOUT });
package/src/steps/form.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { locator, setFieldValue } from '@letsrunit/playwright';
1
+ import { fuzzyLocator, setFieldValue } from '@letsrunit/playwright';
2
2
  import { type Scalar, sleep } from '@letsrunit/utils';
3
3
  import { When } from './wrappers';
4
4
 
@@ -6,7 +6,7 @@ const TIMEOUT = 500;
6
6
  const DELAY = 500;
7
7
 
8
8
  export const set = When('I set {locator} to {value}', async function (selector: string, value: Scalar | Scalar[]) {
9
- const el = await locator(this.page, selector);
9
+ const el = await fuzzyLocator(this.page, selector);
10
10
  await setFieldValue(el, value, { timeout: TIMEOUT });
11
11
  await sleep(DELAY);
12
12
  });
@@ -14,15 +14,14 @@ export const set = When('I set {locator} to {value}', async function (selector:
14
14
  export const setRange = When(
15
15
  'I set {locator} to range of {value} to {value}',
16
16
  async function (selector: string, from: Scalar, to: Scalar) {
17
- const el = await locator(this.page, selector);
17
+ const el = await fuzzyLocator(this.page, selector);
18
18
  await setFieldValue(el, { from, to }, { timeout: TIMEOUT });
19
19
  await sleep(DELAY);
20
20
  },
21
21
  );
22
22
 
23
-
24
23
  export const clear = When('I clear {locator}', async function (selector) {
25
- const el = await locator(this.page, selector);
24
+ const el = await fuzzyLocator(this.page, selector);
26
25
  await setFieldValue(el, null, { timeout: TIMEOUT });
27
26
  await sleep(DELAY);
28
27
  });
@@ -30,7 +29,7 @@ export const clear = When('I clear {locator}', async function (selector) {
30
29
  export const check = When(
31
30
  'I {check|uncheck} {locator}',
32
31
  async function (check: boolean, selector: string) {
33
- const el = await locator(this.page, selector);
32
+ const el = await fuzzyLocator(this.page, selector);
34
33
  await setFieldValue(el, check, { timeout: TIMEOUT });
35
34
  await sleep(DELAY);
36
35
  },
@@ -38,7 +37,7 @@ export const check = When(
38
37
  );
39
38
 
40
39
  export const focus = When('I {focus|blur} {locator}', async function (focus: boolean, selector: string) {
41
- const el = await locator(this.page, selector);
40
+ const el = await fuzzyLocator(this.page, selector);
42
41
 
43
42
  if (focus) {
44
43
  await el.focus({ timeout: TIMEOUT });
@@ -1,5 +1,5 @@
1
1
  import type { KeyCombo } from '@letsrunit/gherkin';
2
- import { locator, waitAfterInteraction } from '@letsrunit/playwright';
2
+ import { fuzzyLocator, waitAfterInteraction } from '@letsrunit/playwright';
3
3
  import type { Locator } from '@playwright/test';
4
4
  import { When } from './wrappers';
5
5
 
@@ -24,7 +24,7 @@ export const click = When(
24
24
  async function (action: MouseAction, selector: string) {
25
25
  const prevUrl = this.page.url();
26
26
 
27
- const el = await locator(this.page, selector);
27
+ const el = await fuzzyLocator(this.page, selector);
28
28
  await press(el, action);
29
29
 
30
30
  await waitAfterInteraction(this.page, el, { prevUrl });
@@ -36,7 +36,7 @@ export const clickHold = When(
36
36
  async function (action: MouseAction, selector: string, combo: KeyCombo) {
37
37
  const prevUrl = this.page.url();
38
38
 
39
- const el = await locator(this.page, selector);
39
+ const el = await fuzzyLocator(this.page, selector);
40
40
  const keys = [...combo.modifiers, combo.key];
41
41
 
42
42
  for (const m of keys) await this.page.keyboard.down(m);
@@ -48,6 +48,6 @@ export const clickHold = When(
48
48
  );
49
49
 
50
50
  export const scroll = When('I scroll {locator} into view', async function (selector: string) {
51
- const el = await locator(this.page, selector);
51
+ const el = await fuzzyLocator(this.page, selector);
52
52
  await el.scrollIntoViewIfNeeded({ timeout: TIMEOUT });
53
53
  });
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/parameters.ts","../src/steps/assert.ts","../src/utils/test-helpers.ts","../src/steps/wrappers.ts","../src/steps/clipboard.ts","../src/steps/form.ts","../src/steps/keyboard.ts","../src/steps/mailbox.ts","../src/steps/mouse.ts","../src/steps/navigation.ts","../src/utils/get-lang.ts","../src/steps/index.ts"],"names":["contain","locator","TIMEOUT","check","focus","DELAY","sleep","press","expect"],"mappings":"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","file":"chunk-YT56PTQF.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', 'not contains', /((?:not )?contains)/),\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];\n","import { locator } from '@letsrunit/playwright';\nimport { expectOrNot } from '../utils/test-helpers';\nimport { Then } from './wrappers';\n\nconst WAIT_TIMEOUT = 5000;\n\nexport const see = Then(\n 'The page {contains|not contains} {locator}',\n async function (visible: boolean, selector: string) {\n const el = await locator(this.page, selector);\n await expectOrNot(el, visible).toBeVisible({ timeout: WAIT_TIMEOUT });\n },\n);\n\nexport const contain = Then(\n '{locator} {contains|not contains} {locator}',\n async function (selector: string, contain: boolean, child: string) {\n const el = await locator(this.page, selector);\n const childElement = el.locator(child);\n await expectOrNot(childElement, contain).toBeAttached({ timeout: WAIT_TIMEOUT });\n },\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 type { StepDefinition, StepHandler } from '../types';\n\nexport function Given(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n return { type: 'Given', expression, fn, comment };\n}\n\nexport function When(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n return { type: 'When', expression, fn, comment };\n}\n\nexport function Then(expression: string | RegExp, fn: StepHandler, comment?: string): StepDefinition {\n return { type: 'Then', expression, fn, comment };\n}\n","import { locator } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from './wrappers';\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 locator(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 locator(this.page, selector);\n const value = this.clipboard?.value || '';\n\n await el.fill(String(value), { timeout: TIMEOUT });\n});\n","import { locator, setFieldValue } from '@letsrunit/playwright';\nimport { type Scalar, sleep } from '@letsrunit/utils';\nimport { When } from './wrappers';\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 locator(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 locator(this.page, selector);\n await setFieldValue(el, { from, to }, { timeout: TIMEOUT });\n await sleep(DELAY);\n },\n);\n\n\nexport const clear = When('I clear {locator}', async function (selector) {\n const el = await locator(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 locator(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 locator(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 './wrappers';\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 './wrappers';\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 type { KeyCombo } from '@letsrunit/gherkin';\nimport { locator, waitAfterInteraction } from '@letsrunit/playwright';\nimport type { Locator } from '@playwright/test';\nimport { When } from './wrappers';\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 locator(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 locator(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 locator(this.page, selector);\n await el.scrollIntoViewIfNeeded({ timeout: TIMEOUT });\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 './wrappers';\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 { 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 type { StepDefinition } from '../types';\nimport * as assert from './assert';\nimport * as clipboard from './clipboard';\nimport * as form from './form';\nimport * as keyboard from './keyboard';\nimport * as mailbox from './mailbox';\nimport * as mouse from './mouse';\nimport * as navigation from './navigation';\n\n// The order matters for the LLM\nexport const stepsDefinitions: StepDefinition[] = [\n ...Object.values(assert),\n ...Object.values(navigation),\n ...Object.values(mouse),\n ...Object.values(form),\n ...Object.values(keyboard),\n ...Object.values(mailbox),\n ...Object.values(clipboard),\n];\n"]}