@esimplicitylabs/katalyst-xspec 0.6.0 → 0.7.1

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.
@@ -93,23 +93,23 @@ function registerApiHttpSteps(test) {
93
93
  world.lastContentType = result.contentType;
94
94
  world.lastResponse = result.response;
95
95
  }
96
- When("I GET {string}", { tags: "@api or @hybrid" }, async ({ api, world }, path) => {
96
+ When("I GET {string}", async ({ api, world }, path) => {
97
97
  await send({ api, world }, "GET", path);
98
98
  });
99
- When("I DELETE {string}", { tags: "@api or @hybrid" }, async ({ api, world }, path) => {
99
+ When("I DELETE {string}", async ({ api, world }, path) => {
100
100
  await send({ api, world }, "DELETE", path);
101
101
  });
102
- When("I POST {string} with JSON body:", { tags: "@api or @hybrid" }, async ({ api, world }, path, docString) => {
102
+ When("I POST {string} with JSON body:", async ({ api, world }, path, docString) => {
103
103
  const interpolated = interpolate(docString ?? "", world.vars);
104
104
  const parsed = tryParseJson(interpolated) ?? interpolated;
105
105
  await send({ api, world }, "POST", path, parsed);
106
106
  });
107
- When("I PATCH {string} with JSON body:", { tags: "@api or @hybrid" }, async ({ api, world }, path, docString) => {
107
+ When("I PATCH {string} with JSON body:", async ({ api, world }, path, docString) => {
108
108
  const interpolated = interpolate(docString ?? "", world.vars);
109
109
  const parsed = tryParseJson(interpolated) ?? interpolated;
110
110
  await send({ api, world }, "PATCH", path, parsed);
111
111
  });
112
- When("I PUT {string} with JSON body:", { tags: "@api or @hybrid" }, async ({ api, world }, path, docString) => {
112
+ When("I PUT {string} with JSON body:", async ({ api, world }, path, docString) => {
113
113
  const interpolated = interpolate(docString ?? "", world.vars);
114
114
  const parsed = tryParseJson(interpolated) ?? interpolated;
115
115
  await send({ api, world }, "PUT", path, parsed);
@@ -121,22 +121,22 @@ import { createBdd as createBdd2 } from "playwright-bdd";
121
121
  import { expect as expect2 } from "@playwright/test";
122
122
  function registerApiAssertionSteps(test) {
123
123
  const { Then } = createBdd2(test);
124
- Then("the response status should be {int}", { tags: "@api or @hybrid" }, async ({ world }, code) => {
124
+ Then("the response status should be {int}", async ({ world }, code) => {
125
125
  expect2(world.lastStatus, `Unexpected status. Body: ${world.lastText}`).toBe(code);
126
126
  });
127
- Then("the response should be a JSON array", { tags: "@api or @hybrid" }, async ({ world }) => {
127
+ Then("the response should be a JSON array", async ({ world }) => {
128
128
  expect2(Array.isArray(world.lastJson), `Expected JSON array. Body: ${world.lastText}`).toBe(true);
129
129
  });
130
- Then("the response should be a JSON object", { tags: "@api or @hybrid" }, async ({ world }) => {
130
+ Then("the response should be a JSON object", async ({ world }) => {
131
131
  const v = world.lastJson;
132
132
  expect2(v !== null && typeof v === "object" && !Array.isArray(v), `Expected JSON object. Body: ${world.lastText}`).toBe(true);
133
133
  });
134
- Then("the value at {string} should equal {string}", { tags: "@api or @hybrid" }, async ({ world }, path, expectedRaw) => {
134
+ Then("the value at {string} should equal {string}", async ({ world }, path, expectedRaw) => {
135
135
  const actual = selectPath(world.lastJson, path);
136
136
  const expected = parseExpected(expectedRaw, world);
137
137
  expect2(actual).toEqual(expected);
138
138
  });
139
- Then("I store the value at {string} as {string}", { tags: "@api or @hybrid" }, async ({ world, cleanup }, path, varName) => {
139
+ Then("I store the value at {string} as {string}", async ({ world, cleanup }, path, varName) => {
140
140
  const val = selectPath(world.lastJson, path);
141
141
  world.vars[varName] = String(val);
142
142
  cleanup.registerFromVar(world, varName, val, world.lastJson);
@@ -147,13 +147,13 @@ function registerApiAssertionSteps(test) {
147
147
  import { createBdd as createBdd3 } from "playwright-bdd";
148
148
  function registerApiAuthSteps(test) {
149
149
  const { Given } = createBdd3(test);
150
- Given("I am authenticated as an admin via API", { tags: "@api or @hybrid" }, async ({ auth, world }) => {
150
+ Given("I am authenticated as an admin via API", async ({ auth, world }) => {
151
151
  await auth.apiLoginAsAdmin(world);
152
152
  });
153
- Given("I am authenticated as a user via API", { tags: "@api or @hybrid" }, async ({ auth, world }) => {
153
+ Given("I am authenticated as a user via API", async ({ auth, world }) => {
154
154
  await auth.apiLoginAsUser(world);
155
155
  });
156
- Given("I set bearer token from variable {string}", { tags: "@api or @hybrid" }, async ({ auth, world }, varName) => {
156
+ Given("I set bearer token from variable {string}", async ({ auth, world }, varName) => {
157
157
  const token = world.vars[varName];
158
158
  if (!token) throw new Error(`No token found in variable '${varName}'`);
159
159
  auth.apiSetBearer(world, token);
@@ -164,7 +164,7 @@ function registerApiAuthSteps(test) {
164
164
  import { createBdd as createBdd4 } from "playwright-bdd";
165
165
  function registerHybridSteps(test) {
166
166
  const { Given } = createBdd4(test);
167
- Given("I navigate to interpolated path {string}", { tags: "@hybrid" }, async ({ ui, world }, path) => {
167
+ Given("I navigate to interpolated path {string}", async ({ ui, world }, path) => {
168
168
  await ui.goto(interpolate(path, world.vars));
169
169
  });
170
170
  }
@@ -332,42 +332,41 @@ async function expectElementAttribute(page, selector, attribute, value, options)
332
332
  // src/steps/ui.basic.ts
333
333
  function registerUiBasicSteps(test) {
334
334
  const { Given, When, Then } = createBdd8(test);
335
- Given("I navigate to {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, path) => {
335
+ Given("I navigate to {string}", async ({ ui, world }, path) => {
336
336
  await ui.goto(interpolate(path, world.vars));
337
337
  });
338
- When("I click the button {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, name) => {
338
+ When("I click the button {string}", async ({ ui, world }, name) => {
339
339
  await ui.clickButton(interpolate(name, world.vars));
340
340
  });
341
- When("I click the {string} button", { tags: "@ui or @hybrid" }, async ({ ui, world }, name) => {
341
+ When("I click the {string} button", async ({ ui, world }, name) => {
342
342
  await ui.clickButton(interpolate(name, world.vars));
343
343
  });
344
- When("I click the link {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, name) => {
344
+ When("I click the link {string}", async ({ ui, world }, name) => {
345
345
  await ui.clickLink(interpolate(name, world.vars));
346
346
  });
347
- When("I fill the placeholder {string} with {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, placeholder, value) => {
347
+ When("I fill the placeholder {string} with {string}", async ({ ui, world }, placeholder, value) => {
348
348
  await ui.fillPlaceholder(interpolate(placeholder, world.vars), interpolate(value, world.vars));
349
349
  });
350
- When("I fill the field {string} with {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, label, value) => {
350
+ When("I fill the field {string} with {string}", async ({ ui, world }, label, value) => {
351
351
  await ui.fillLabel(interpolate(label, world.vars), interpolate(value, world.vars));
352
352
  });
353
- When("I fill in {string} with {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, label, value) => {
353
+ When("I fill in {string} with {string}", async ({ ui, world }, label, value) => {
354
354
  await ui.fillLabel(interpolate(label, world.vars), interpolate(value, world.vars));
355
355
  });
356
- When("I log in as admin in UI", { tags: "@ui or @hybrid" }, async ({ auth, world }) => {
356
+ When("I log in as admin in UI", async ({ auth, world }) => {
357
357
  await auth.uiLoginAsAdmin(world);
358
358
  });
359
- When("I log in as user in UI", { tags: "@ui or @hybrid" }, async ({ auth, world }) => {
359
+ When("I log in as user in UI", async ({ auth, world }) => {
360
360
  await auth.uiLoginAsUser(world);
361
361
  });
362
- When("I click the element {string}", { tags: "@ui or @hybrid" }, async ({ page, world }, selector) => {
362
+ When("I click the element {string}", async ({ page, world }, selector) => {
363
363
  await page.locator(interpolate(selector, world.vars)).click();
364
364
  });
365
- When("I select {string} from dropdown {string}", { tags: "@ui or @hybrid" }, async ({ page, world }, option, selector) => {
365
+ When("I select {string} from dropdown {string}", async ({ page, world }, option, selector) => {
366
366
  await page.locator(interpolate(selector, world.vars)).selectOption({ label: interpolate(option, world.vars) });
367
367
  });
368
368
  When(
369
369
  "I set the file input {string} to a file named {string} with content {string}",
370
- { tags: "@ui or @hybrid" },
371
370
  async ({ page, world }, selector, fileName, content) => {
372
371
  await setFileInputContent(
373
372
  page,
@@ -377,25 +376,25 @@ function registerUiBasicSteps(test) {
377
376
  );
378
377
  }
379
378
  );
380
- Then("I should see text {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, text) => {
379
+ Then("I should see text {string}", async ({ ui, world }, text) => {
381
380
  await ui.expectText(interpolate(text, world.vars));
382
381
  });
383
- Then("the URL should contain {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, part) => {
382
+ Then("the URL should contain {string}", async ({ ui, world }, part) => {
384
383
  await ui.expectUrlContains(interpolate(part, world.vars));
385
384
  });
386
- Then("I should be on page {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, path) => {
385
+ Then("I should be on page {string}", async ({ ui, world }, path) => {
387
386
  await ui.expectUrlContains(interpolate(path, world.vars));
388
387
  });
389
- Then("the element {string} should be visible", { tags: "@ui or @hybrid" }, async ({ page, world }, selector) => {
388
+ Then("the element {string} should be visible", async ({ page, world }, selector) => {
390
389
  await expect4(page.locator(interpolate(selector, world.vars))).toBeVisible();
391
390
  });
392
- Then("the element {string} should not be visible", { tags: "@ui or @hybrid" }, async ({ page, world }, selector) => {
391
+ Then("the element {string} should not be visible", async ({ page, world }, selector) => {
393
392
  await expect4(page.locator(interpolate(selector, world.vars))).not.toBeVisible();
394
393
  });
395
- Then("the element {string} should have value {string}", { tags: "@ui or @hybrid" }, async ({ page, world }, selector, value) => {
394
+ Then("the element {string} should have value {string}", async ({ page, world }, selector, value) => {
396
395
  await expect4(page.locator(interpolate(selector, world.vars))).toHaveValue(interpolate(value, world.vars));
397
396
  });
398
- Then("the element {string} should have attribute {string} equal to {string}", { tags: "@ui or @hybrid" }, async ({ page, world }, selector, attribute, value) => {
397
+ Then("the element {string} should have attribute {string} equal to {string}", async ({ page, world }, selector, attribute, value) => {
399
398
  await expectElementAttribute(
400
399
  page,
401
400
  interpolate(selector, world.vars),
@@ -403,10 +402,10 @@ function registerUiBasicSteps(test) {
403
402
  interpolate(value, world.vars)
404
403
  );
405
404
  });
406
- Then("the element {string} should be checked", { tags: "@ui or @hybrid" }, async ({ page, world }, selector) => {
405
+ Then("the element {string} should be checked", async ({ page, world }, selector) => {
407
406
  await expect4(page.locator(interpolate(selector, world.vars))).toBeChecked();
408
407
  });
409
- Then("the element {string} should not be checked", { tags: "@ui or @hybrid" }, async ({ page, world }, selector) => {
408
+ Then("the element {string} should not be checked", async ({ page, world }, selector) => {
410
409
  await expect4(page.locator(interpolate(selector, world.vars))).not.toBeChecked();
411
410
  });
412
411
  }
@@ -511,36 +510,35 @@ function parseRegex(input) {
511
510
  }
512
511
  function registerWizardSteps(test) {
513
512
  const { Given, When, Then } = createBdd9(test);
514
- Given("I open {string} page", { tags: "@ui or @hybrid" }, async ({ ui, world }, urlOrVar) => {
513
+ Given("I open {string} page", async ({ ui, world }, urlOrVar) => {
515
514
  await ui.goto(resolveValue(urlOrVar, world));
516
515
  });
517
- Given("I open {string} in the browser", { tags: "@ui or @hybrid" }, async ({ ui, world }, urlOrVar) => {
516
+ Given("I open {string} in the browser", async ({ ui, world }, urlOrVar) => {
518
517
  await ui.goto(resolveValue(urlOrVar, world));
519
518
  });
520
- When("I go back in the browser", { tags: "@ui or @hybrid" }, async ({ ui }) => {
519
+ When("I go back in the browser", async ({ ui }) => {
521
520
  await ui.goBack();
522
521
  });
523
- When("I save the current URL as {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, varName) => {
522
+ When("I save the current URL as {string}", async ({ ui, world }, varName) => {
524
523
  world.vars[varName] = await ui.getCurrentUrl();
525
524
  });
526
- When("I save the current url as {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, varName) => {
525
+ When("I save the current url as {string}", async ({ ui, world }, varName) => {
527
526
  world.vars[varName] = await ui.getCurrentUrl();
528
527
  });
529
- Then("I zoom to {string} in the browser", { tags: "@ui or @hybrid" }, async ({ ui, world }, scale) => {
528
+ Then("I zoom to {string} in the browser", async ({ ui, world }, scale) => {
530
529
  await ui.zoomTo(parseNumber(scale, world));
531
530
  });
532
- When("I reload the page", { tags: "@ui or @hybrid" }, async ({ ui }) => {
531
+ When("I reload the page", async ({ ui }) => {
533
532
  await ui.reload();
534
533
  });
535
- Then("I wait {string} seconds", { tags: "@ui or @hybrid" }, async ({ ui, world }, seconds) => {
534
+ Then("I wait {string} seconds", async ({ ui, world }, seconds) => {
536
535
  await ui.waitSeconds(parseNumber(seconds, world));
537
536
  });
538
- Then("I wait for the page to load", { tags: "@ui or @hybrid" }, async ({ ui }) => {
537
+ Then("I wait for the page to load", async ({ ui }) => {
539
538
  await ui.waitForPageLoad();
540
539
  });
541
540
  When(
542
541
  "I get a part of the URL based on {string} regular expression and save it as {string}",
543
- { tags: "@ui or @hybrid" },
544
542
  async ({ ui, world }, regexString, varName) => {
545
543
  const url = await ui.getCurrentUrl();
546
544
  const regex = parseRegex(resolveValue(regexString, world));
@@ -549,7 +547,7 @@ function registerWizardSteps(test) {
549
547
  world.vars[varName] = match[1] ?? match[0];
550
548
  }
551
549
  );
552
- Then("I {string} {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, action, value) => {
550
+ Then("I {string} {string}", async ({ ui, world }, action, value) => {
553
551
  const verb = action.trim().toLowerCase();
554
552
  const resolved = resolveValue(value, world);
555
553
  if (verb === "type") {
@@ -564,7 +562,6 @@ function registerWizardSteps(test) {
564
562
  });
565
563
  When(
566
564
  "I {string} the {string} element that contains {string}",
567
- { tags: "@ui or @hybrid" },
568
565
  async ({ ui, world }, clickMode, elementType, text) => {
569
566
  await ui.clickElementThatContains(
570
567
  asClickMode(resolveValue(clickMode, world)),
@@ -575,7 +572,6 @@ function registerWizardSteps(test) {
575
572
  );
576
573
  When(
577
574
  "I {string} the {string} element with {string} {string}",
578
- { tags: "@ui or @hybrid" },
579
575
  async ({ ui, world }, clickMode, ordinal, text, method) => {
580
576
  await ui.clickElementWith(
581
577
  asClickMode(resolveValue(clickMode, world)),
@@ -585,12 +581,11 @@ function registerWizardSteps(test) {
585
581
  );
586
582
  }
587
583
  );
588
- When("I click on the top left corner of the page", { tags: "@ui or @hybrid" }, async ({ page }) => {
584
+ When("I click on the top left corner of the page", async ({ page }) => {
589
585
  await page.mouse.click(0, 0);
590
586
  });
591
587
  When(
592
588
  "If its visible, I {string} the {string} element with {string} {string}",
593
- { tags: "@ui or @hybrid" },
594
589
  async ({ page, ui, world }, clickMode, ordinal, text, method) => {
595
590
  const idx = parseOrdinalIndex(ordinal, world);
596
591
  const resolvedText = resolveValue(text, world);
@@ -601,12 +596,11 @@ function registerWizardSteps(test) {
601
596
  await ui.clickElementWith(asClickMode(resolveValue(clickMode, world)), ordinal, resolvedText, resolvedMethod);
602
597
  }
603
598
  );
604
- Then("I fill {string} into the {string} dropdown", { tags: "@ui or @hybrid" }, async ({ ui, world }, value, label) => {
599
+ Then("I fill {string} into the {string} dropdown", async ({ ui, world }, value, label) => {
605
600
  await ui.fillDropdown(resolveValue(value, world), resolveValue(label, world));
606
601
  });
607
602
  When(
608
603
  "I {string} {string} in the {string} element with {string} {string}",
609
- { tags: "@ui or @hybrid" },
610
604
  async ({ ui, world }, action, value, ordinal, text, method) => {
611
605
  await ui.inputInElement(
612
606
  asInputMode(resolveValue(action, world)),
@@ -619,33 +613,30 @@ function registerWizardSteps(test) {
619
613
  );
620
614
  Then(
621
615
  "I verify if a new tab which URL {string} {string} opens",
622
- { tags: "@ui or @hybrid" },
623
616
  async ({ ui, world }, mode, expected) => {
624
617
  await ui.expectNewTabUrl(asUrlAssertMode(resolveValue(mode, world)), resolveValue(expected, world));
625
618
  }
626
619
  );
627
620
  Then(
628
621
  "I verify if a new tab which url {string} {string} opens",
629
- { tags: "@ui or @hybrid" },
630
622
  async ({ ui, world }, mode, expected) => {
631
623
  await ui.expectNewTabUrl(asUrlAssertMode(resolveValue(mode, world)), resolveValue(expected, world));
632
624
  }
633
625
  );
634
- Then("I verify if the URL {string} {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, mode, expected) => {
626
+ Then("I verify if the URL {string} {string}", async ({ ui, world }, mode, expected) => {
635
627
  await ui.expectUrl(asUrlAssertMode(resolveValue(mode, world)), resolveValue(expected, world));
636
628
  });
637
- Then("I verify if the url {string} {string}", { tags: "@ui or @hybrid" }, async ({ ui, world }, mode, expected) => {
629
+ Then("I verify if the url {string} {string}", async ({ ui, world }, mode, expected) => {
638
630
  await ui.expectUrl(asUrlAssertMode(resolveValue(mode, world)), resolveValue(expected, world));
639
631
  });
640
- Then("I verify if the URL {string} {string} opens", { tags: "@ui or @hybrid" }, async ({ ui, world }, mode, expected) => {
632
+ Then("I verify if the URL {string} {string} opens", async ({ ui, world }, mode, expected) => {
641
633
  await ui.expectUrl(asUrlAssertMode(resolveValue(mode, world)), resolveValue(expected, world));
642
634
  });
643
- Then("I verify if the url {string} {string} opens", { tags: "@ui or @hybrid" }, async ({ ui, world }, mode, expected) => {
635
+ Then("I verify if the url {string} {string} opens", async ({ ui, world }, mode, expected) => {
644
636
  await ui.expectUrl(asUrlAssertMode(resolveValue(mode, world)), resolveValue(expected, world));
645
637
  });
646
638
  Then(
647
639
  "I verify that a {string} element with {string} text {string} visible",
648
- { tags: "@ui or @hybrid" },
649
640
  async ({ ui, world }, elementType, text, assertion) => {
650
641
  const normalized = resolveValue(assertion, world).trim().toLowerCase();
651
642
  const shouldBeVisible = normalized === "is";
@@ -657,7 +648,6 @@ function registerWizardSteps(test) {
657
648
  );
658
649
  Then(
659
650
  "I verify that {string} element with {string} {string} is {string}",
660
- { tags: "@ui or @hybrid" },
661
651
  async ({ ui, world }, ordinal, text, method, state) => {
662
652
  await ui.expectElementState(
663
653
  resolveValue(ordinal, world),
@@ -669,7 +659,6 @@ function registerWizardSteps(test) {
669
659
  );
670
660
  Then(
671
661
  "I verify that {string} element with {string} {string} becomes {string} during {string} seconds",
672
- { tags: "@ui or @hybrid" },
673
662
  async ({ ui, world }, ordinal, text, method, state, seconds) => {
674
663
  await ui.expectElementStateWithin(
675
664
  resolveValue(ordinal, world),
@@ -688,7 +677,6 @@ function registerFormSteps(test) {
688
677
  const { Given, When } = createBdd10(test);
689
678
  When(
690
679
  "I fill the form:",
691
- { tags: "@ui or @hybrid" },
692
680
  async ({ ui, world }, dataTable) => {
693
681
  const rows = dataTable.hashes ? dataTable.hashes() : dataTable.rawTable?.slice(1).map((row) => ({
694
682
  field: row[0],
@@ -703,7 +691,6 @@ function registerFormSteps(test) {
703
691
  );
704
692
  When(
705
693
  "I fill the form with {string} locators:",
706
- { tags: "@ui or @hybrid" },
707
694
  async ({ ui, world }, locatorMethod, dataTable) => {
708
695
  const rows = dataTable.hashes ? dataTable.hashes() : dataTable.rawTable?.slice(1).map((row) => ({
709
696
  field: row[0],
@@ -718,7 +705,6 @@ function registerFormSteps(test) {
718
705
  );
719
706
  When(
720
707
  "I fill and submit the form:",
721
- { tags: "@ui or @hybrid" },
722
708
  async ({ ui, world }, dataTable) => {
723
709
  const rows = dataTable.hashes ? dataTable.hashes() : dataTable.rawTable?.slice(1).map((row) => ({
724
710
  field: row[0],
@@ -734,7 +720,6 @@ function registerFormSteps(test) {
734
720
  );
735
721
  Given(
736
722
  "I clear and fill the form:",
737
- { tags: "@ui or @hybrid" },
738
723
  async ({ page, world }, dataTable) => {
739
724
  const rows = dataTable.hashes ? dataTable.hashes() : dataTable.rawTable?.slice(1).map((row) => ({
740
725
  field: row[0],
@@ -757,7 +742,6 @@ function registerDebugSteps(test) {
757
742
  const { When, Then } = createBdd11(test);
758
743
  When(
759
744
  "I capture the page HTML as {string}",
760
- { tags: "@ui or @hybrid" },
761
745
  async ({ page, world }, varName) => {
762
746
  const content = await page.content();
763
747
  world.vars[varName] = content;
@@ -765,14 +749,12 @@ function registerDebugSteps(test) {
765
749
  );
766
750
  Then(
767
751
  "I log the current URL",
768
- { tags: "@ui or @hybrid" },
769
752
  async ({ page }) => {
770
753
  console.log(`[DEBUG] Current URL: ${page.url()}`);
771
754
  }
772
755
  );
773
756
  Then(
774
757
  "I log the page title",
775
- { tags: "@ui or @hybrid" },
776
758
  async ({ page }) => {
777
759
  const title = await page.title();
778
760
  console.log(`[DEBUG] Page title: ${title}`);
@@ -780,7 +762,6 @@ function registerDebugSteps(test) {
780
762
  );
781
763
  When(
782
764
  "I save a screenshot as {string}",
783
- { tags: "@ui or @hybrid" },
784
765
  async ({ page, world }, filename) => {
785
766
  const resolvedFilename = interpolate(filename, world.vars);
786
767
  await page.screenshot({ path: resolvedFilename });
@@ -789,7 +770,6 @@ function registerDebugSteps(test) {
789
770
  );
790
771
  When(
791
772
  "I save a full page screenshot as {string}",
792
- { tags: "@ui or @hybrid" },
793
773
  async ({ page, world }, filename) => {
794
774
  const resolvedFilename = interpolate(filename, world.vars);
795
775
  await page.screenshot({ path: resolvedFilename, fullPage: true });
@@ -798,7 +778,6 @@ function registerDebugSteps(test) {
798
778
  );
799
779
  When(
800
780
  "I pause for debugging",
801
- { tags: "@ui or @hybrid" },
802
781
  async ({ page }) => {
803
782
  console.log('[DEBUG] Pausing for debugging. Press "Resume" in Playwright Inspector to continue.');
804
783
  await page.pause();
@@ -806,7 +785,6 @@ function registerDebugSteps(test) {
806
785
  );
807
786
  Then(
808
787
  "I print visible text",
809
- { tags: "@ui or @hybrid" },
810
788
  async ({ page }) => {
811
789
  const text = await page.innerText("body");
812
790
  const truncated = text.length > 2e3 ? `${text.substring(0, 2e3)}...(truncated)` : text;
@@ -816,7 +794,6 @@ ${truncated}`);
816
794
  );
817
795
  Then(
818
796
  "I count elements matching {string}",
819
- { tags: "@ui or @hybrid" },
820
797
  async ({ page, world }, selector) => {
821
798
  const resolvedSelector = interpolate(selector, world.vars);
822
799
  const count = await page.locator(resolvedSelector).count();
@@ -825,7 +802,6 @@ ${truncated}`);
825
802
  );
826
803
  Then(
827
804
  "I print browser console messages",
828
- { tags: "@ui or @hybrid" },
829
805
  async ({ page }) => {
830
806
  console.log("[DEBUG] Browser console messages will be captured from this point.");
831
807
  page.on("console", (msg) => {
@@ -835,7 +811,6 @@ ${truncated}`);
835
811
  );
836
812
  When(
837
813
  "I capture viewport size",
838
- { tags: "@ui or @hybrid" },
839
814
  async ({ page, world }) => {
840
815
  const viewport = page.viewportSize();
841
816
  if (viewport) {
@@ -849,7 +824,6 @@ ${truncated}`);
849
824
  );
850
825
  Then(
851
826
  "I log all cookies",
852
- { tags: "@ui or @hybrid" },
853
827
  async ({ page }) => {
854
828
  const context = page.context();
855
829
  const cookies = await context.cookies();
@@ -861,7 +835,6 @@ ${truncated}`);
861
835
  );
862
836
  Then(
863
837
  "I log localStorage",
864
- { tags: "@ui or @hybrid" },
865
838
  async ({ page }) => {
866
839
  const storage = await page.evaluate(() => {
867
840
  const items = {};
@@ -882,7 +855,6 @@ ${truncated}`);
882
855
  );
883
856
  When(
884
857
  "I highlight element {string}",
885
- { tags: "@ui or @hybrid" },
886
858
  async ({ page, world }, selector) => {
887
859
  const resolvedSelector = interpolate(selector, world.vars);
888
860
  await page.evaluate((sel) => {
@@ -904,7 +876,6 @@ function registerLayoutSteps(test) {
904
876
  const { Given, When, Then } = createBdd12(test);
905
877
  Then(
906
878
  "I should see the {string} panel",
907
- { tags: "@ui or @hybrid" },
908
879
  async ({ page, world }, panelName) => {
909
880
  const resolvedName = interpolate(panelName, world.vars);
910
881
  const panel = page.getByTestId(`${resolvedName}-panel`);
@@ -913,7 +884,6 @@ function registerLayoutSteps(test) {
913
884
  );
914
885
  Then(
915
886
  "I should not see the {string} panel",
916
- { tags: "@ui or @hybrid" },
917
887
  async ({ page, world }, panelName) => {
918
888
  const resolvedName = interpolate(panelName, world.vars);
919
889
  const panel = page.getByTestId(`${resolvedName}-panel`);
@@ -922,7 +892,6 @@ function registerLayoutSteps(test) {
922
892
  );
923
893
  Then(
924
894
  "the {string} panel should be {string}",
925
- { tags: "@ui or @hybrid" },
926
895
  async ({ page, world }, panelName, state) => {
927
896
  const resolvedName = interpolate(panelName, world.vars);
928
897
  const panel = page.getByTestId(`${resolvedName}-panel`);
@@ -937,7 +906,6 @@ function registerLayoutSteps(test) {
937
906
  );
938
907
  Then(
939
908
  "the {string} panel should be full width",
940
- { tags: "@ui or @hybrid" },
941
909
  async ({ page, world }, panelName) => {
942
910
  const resolvedName = interpolate(panelName, world.vars);
943
911
  const panel = page.getByTestId(`${resolvedName}-panel`);
@@ -949,7 +917,6 @@ function registerLayoutSteps(test) {
949
917
  );
950
918
  Then(
951
919
  "the {string} panel should be narrow",
952
- { tags: "@ui or @hybrid" },
953
920
  async ({ page, world }, panelName) => {
954
921
  const resolvedName = interpolate(panelName, world.vars);
955
922
  const panel = page.getByTestId(`${resolvedName}-panel`);
@@ -961,7 +928,6 @@ function registerLayoutSteps(test) {
961
928
  );
962
929
  Then(
963
930
  "I should see a split view layout",
964
- { tags: "@ui or @hybrid" },
965
931
  async ({ page }) => {
966
932
  const splitContainer = page.locator("[data-testid='split-view'], .split-view, [data-split-view]");
967
933
  await expect5(splitContainer.first()).toBeVisible();
@@ -969,7 +935,6 @@ function registerLayoutSteps(test) {
969
935
  );
970
936
  Then(
971
937
  "I should not see a split view layout",
972
- { tags: "@ui or @hybrid" },
973
938
  async ({ page }) => {
974
939
  const splitContainer = page.locator("[data-testid='split-view'], .split-view, [data-split-view]");
975
940
  const count = await splitContainer.count();
@@ -978,7 +943,6 @@ function registerLayoutSteps(test) {
978
943
  );
979
944
  Then(
980
945
  "the sidebar should be visible",
981
- { tags: "@ui or @hybrid" },
982
946
  async ({ page }) => {
983
947
  const sidebar = page.locator("[data-testid='sidebar'], aside, nav.sidebar, .sidebar");
984
948
  await expect5(sidebar.first()).toBeVisible();
@@ -986,7 +950,6 @@ function registerLayoutSteps(test) {
986
950
  );
987
951
  Then(
988
952
  "the sidebar should be hidden",
989
- { tags: "@ui or @hybrid" },
990
953
  async ({ page }) => {
991
954
  const sidebar = page.locator("[data-testid='sidebar'], aside.sidebar, nav.sidebar");
992
955
  const count = await sidebar.count();
@@ -997,7 +960,6 @@ function registerLayoutSteps(test) {
997
960
  );
998
961
  Then(
999
962
  "the sidebar should be collapsed",
1000
- { tags: "@ui or @hybrid" },
1001
963
  async ({ page }) => {
1002
964
  const sidebar = page.locator("[data-testid='sidebar'], aside, nav.sidebar, .sidebar").first();
1003
965
  const isCollapsed = await sidebar.evaluate((el) => {
@@ -1008,7 +970,6 @@ function registerLayoutSteps(test) {
1008
970
  );
1009
971
  Then(
1010
972
  "I should see a modal dialog",
1011
- { tags: "@ui or @hybrid" },
1012
973
  async ({ page }) => {
1013
974
  const modal = page.locator("[role='dialog'], [data-testid='modal'], .modal, [aria-modal='true']");
1014
975
  await expect5(modal.first()).toBeVisible();
@@ -1016,7 +977,6 @@ function registerLayoutSteps(test) {
1016
977
  );
1017
978
  Then(
1018
979
  "I should not see a modal dialog",
1019
- { tags: "@ui or @hybrid" },
1020
980
  async ({ page }) => {
1021
981
  const modal = page.locator("[role='dialog'], [data-testid='modal'], .modal, [aria-modal='true']");
1022
982
  const count = await modal.count();
@@ -1027,7 +987,6 @@ function registerLayoutSteps(test) {
1027
987
  );
1028
988
  Then(
1029
989
  "I should see the {string} modal",
1030
- { tags: "@ui or @hybrid" },
1031
990
  async ({ page, world }, modalName) => {
1032
991
  const resolvedName = interpolate(modalName, world.vars);
1033
992
  const modal = page.getByTestId(`${resolvedName}-modal`);
@@ -1036,7 +995,6 @@ function registerLayoutSteps(test) {
1036
995
  );
1037
996
  Given(
1038
997
  "the viewport is {string} size",
1039
- { tags: "@ui or @hybrid" },
1040
998
  async ({ page }, sizeName) => {
1041
999
  const sizes = {
1042
1000
  mobile: { width: 375, height: 667 },
@@ -1053,14 +1011,12 @@ function registerLayoutSteps(test) {
1053
1011
  );
1054
1012
  Given(
1055
1013
  "the viewport is {int}x{int}",
1056
- { tags: "@ui or @hybrid" },
1057
1014
  async ({ page }, width, height) => {
1058
1015
  await page.setViewportSize({ width, height });
1059
1016
  }
1060
1017
  );
1061
1018
  Then(
1062
1019
  "the layout should be responsive",
1063
- { tags: "@ui or @hybrid" },
1064
1020
  async ({ page }) => {
1065
1021
  const original = page.viewportSize();
1066
1022
  await page.setViewportSize({ width: 375, height: 667 });
@@ -1074,7 +1030,6 @@ function registerLayoutSteps(test) {
1074
1030
  );
1075
1031
  Then(
1076
1032
  "the {string} tab should be active",
1077
- { tags: "@ui or @hybrid" },
1078
1033
  async ({ page, world }, tabName) => {
1079
1034
  const resolvedName = interpolate(tabName, world.vars);
1080
1035
  const tab = page.getByRole("tab", { name: resolvedName });
@@ -1083,7 +1038,6 @@ function registerLayoutSteps(test) {
1083
1038
  );
1084
1039
  Then(
1085
1040
  "the {string} tab should not be active",
1086
- { tags: "@ui or @hybrid" },
1087
1041
  async ({ page, world }, tabName) => {
1088
1042
  const resolvedName = interpolate(tabName, world.vars);
1089
1043
  const tab = page.getByRole("tab", { name: resolvedName });
@@ -1092,7 +1046,6 @@ function registerLayoutSteps(test) {
1092
1046
  );
1093
1047
  When(
1094
1048
  "I click the {string} tab",
1095
- { tags: "@ui or @hybrid" },
1096
1049
  async ({ page, world }, tabName) => {
1097
1050
  const resolvedName = interpolate(tabName, world.vars);
1098
1051
  const tab = page.getByRole("tab", { name: resolvedName });
@@ -1174,7 +1127,6 @@ function registerUiAuthSteps(test) {
1174
1127
  const { Given } = createBdd13(test);
1175
1128
  Given(
1176
1129
  "I am authenticated in UI as {string}",
1177
- { tags: "@ui" },
1178
1130
  async ({ page, world }, rolesStr) => {
1179
1131
  const roles = rolesStr.split(",").map((r) => r.trim());
1180
1132
  const testRunId = world.testRunId || world.vars.test_run_id || Date.now();
@@ -1192,7 +1144,6 @@ function registerUiAuthSteps(test) {
1192
1144
  );
1193
1145
  Given(
1194
1146
  "I am authenticated in UI as {string} for tenant {string}",
1195
- { tags: "@ui" },
1196
1147
  async ({ page, world }, rolesStr, tenantId) => {
1197
1148
  const roles = rolesStr.split(",").map((r) => r.trim());
1198
1149
  const testRunId = world.testRunId || world.vars.test_run_id || Date.now();
@@ -1207,7 +1158,6 @@ function registerUiAuthSteps(test) {
1207
1158
  );
1208
1159
  Given(
1209
1160
  "I am authenticated in UI as {string} with id {string}",
1210
- { tags: "@ui" },
1211
1161
  async ({ page, world }, rolesStr, userId) => {
1212
1162
  const roles = rolesStr.split(",").map((r) => r.trim());
1213
1163
  const resolvedUserId = interpolate(userId, world.vars);
@@ -1221,7 +1171,6 @@ function registerUiAuthSteps(test) {
1221
1171
  );
1222
1172
  Given(
1223
1173
  "I am authenticated in UI with bearer token {string}",
1224
- { tags: "@ui" },
1225
1174
  async ({ page, world }, token) => {
1226
1175
  const resolvedToken = interpolate(token, world.vars);
1227
1176
  await setupBearerAuth(page, resolvedToken);
@@ -1230,7 +1179,6 @@ function registerUiAuthSteps(test) {
1230
1179
  );
1231
1180
  Given(
1232
1181
  "I am authenticated in UI with headers:",
1233
- { tags: "@ui" },
1234
1182
  async ({ page, world }, dataTable) => {
1235
1183
  const rows = dataTable.hashes ? dataTable.hashes() : dataTable.rawTable?.slice(1).map((row) => ({
1236
1184
  header: row[0],
@@ -1254,7 +1202,6 @@ function registerUiAuthSteps(test) {
1254
1202
  );
1255
1203
  Given(
1256
1204
  "I switch UI user to {string} with id {string}",
1257
- { tags: "@ui" },
1258
1205
  async ({ page, world }, rolesStr, userId) => {
1259
1206
  const roles = rolesStr.split(",").map((r) => r.trim());
1260
1207
  const resolvedUserId = interpolate(userId, world.vars);
@@ -1272,121 +1219,115 @@ function registerUiAuthSteps(test) {
1272
1219
  import { createBdd as createBdd14 } from "playwright-bdd";
1273
1220
  function registerTuiBasicSteps(test) {
1274
1221
  const { Given, When, Then } = createBdd14(test);
1275
- Given("I start the TUI application", { tags: "@tui" }, async ({ tui }) => {
1222
+ Given("I start the TUI application", async ({ tui }) => {
1276
1223
  await tui.start();
1277
1224
  await tui.waitForReady();
1278
1225
  });
1279
- Given("the TUI application is running", { tags: "@tui" }, async ({ tui }) => {
1226
+ Given("the TUI application is running", async ({ tui }) => {
1280
1227
  if (!tui.isRunning()) {
1281
1228
  await tui.start();
1282
1229
  await tui.waitForReady();
1283
1230
  }
1284
1231
  });
1285
- When("I restart the TUI application", { tags: "@tui" }, async ({ tui }) => {
1232
+ When("I restart the TUI application", async ({ tui }) => {
1286
1233
  await tui.restart();
1287
1234
  await tui.waitForReady();
1288
1235
  });
1289
- When("I stop the TUI application", { tags: "@tui" }, async ({ tui }) => {
1236
+ When("I stop the TUI application", async ({ tui }) => {
1290
1237
  await tui.stop();
1291
1238
  });
1292
- When("I type {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1239
+ When("I type {string}", async ({ tui, world }, text) => {
1293
1240
  await tui.typeText(interpolate(text, world.vars));
1294
1241
  });
1295
- When("I type {string} slowly", { tags: "@tui" }, async ({ tui, world }, text) => {
1242
+ When("I type {string} slowly", async ({ tui, world }, text) => {
1296
1243
  await tui.typeText(interpolate(text, world.vars), { delay: 50 });
1297
1244
  });
1298
- When("I press {string}", { tags: "@tui" }, async ({ tui }, key) => {
1245
+ When("I press {string}", async ({ tui }, key) => {
1299
1246
  await tui.pressKey(key);
1300
1247
  });
1301
- When("I press {string} with ctrl", { tags: "@tui" }, async ({ tui }, key) => {
1248
+ When("I press {string} with ctrl", async ({ tui }, key) => {
1302
1249
  await tui.pressKey(key, { ctrl: true });
1303
1250
  });
1304
- When("I press {string} with alt", { tags: "@tui" }, async ({ tui }, key) => {
1251
+ When("I press {string} with alt", async ({ tui }, key) => {
1305
1252
  await tui.pressKey(key, { alt: true });
1306
1253
  });
1307
- When("I press {string} with shift", { tags: "@tui" }, async ({ tui }, key) => {
1254
+ When("I press {string} with shift", async ({ tui }, key) => {
1308
1255
  await tui.pressKey(key, { shift: true });
1309
1256
  });
1310
- When("I press enter", { tags: "@tui" }, async ({ tui }) => {
1257
+ When("I press enter", async ({ tui }) => {
1311
1258
  await tui.pressKey("enter");
1312
1259
  });
1313
- When("I press tab", { tags: "@tui" }, async ({ tui }) => {
1260
+ When("I press tab", async ({ tui }) => {
1314
1261
  await tui.pressKey("tab");
1315
1262
  });
1316
- When("I press escape", { tags: "@tui" }, async ({ tui }) => {
1263
+ When("I press escape", async ({ tui }) => {
1317
1264
  await tui.pressKey("escape");
1318
1265
  });
1319
1266
  When(
1320
1267
  "I fill the TUI field {string} with {string}",
1321
- { tags: "@tui" },
1322
1268
  async ({ tui, world }, field, value) => {
1323
1269
  await tui.fillField(interpolate(field, world.vars), interpolate(value, world.vars));
1324
1270
  }
1325
1271
  );
1326
1272
  When(
1327
1273
  "I enter {string} in the {string} field",
1328
- { tags: "@tui" },
1329
1274
  async ({ tui, world }, value, field) => {
1330
1275
  await tui.fillField(interpolate(field, world.vars), interpolate(value, world.vars));
1331
1276
  }
1332
1277
  );
1333
- When("I select {string}", { tags: "@tui" }, async ({ tui, world }, option) => {
1278
+ When("I select {string}", async ({ tui, world }, option) => {
1334
1279
  await tui.selectOption(interpolate(option, world.vars));
1335
1280
  });
1336
- When("I select option {string}", { tags: "@tui" }, async ({ tui, world }, option) => {
1281
+ When("I select option {string}", async ({ tui, world }, option) => {
1337
1282
  await tui.selectOption(interpolate(option, world.vars));
1338
1283
  });
1339
- When("I click at position {int}, {int}", { tags: "@tui" }, async ({ tui }, x, y) => {
1284
+ When("I click at position {int}, {int}", async ({ tui }, x, y) => {
1340
1285
  await tui.click(x, y);
1341
1286
  });
1342
- When("I click on {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1287
+ When("I click on {string}", async ({ tui, world }, text) => {
1343
1288
  await tui.clickOnText(interpolate(text, world.vars));
1344
1289
  });
1345
- Then("I should see {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1290
+ Then("I should see {string}", async ({ tui, world }, text) => {
1346
1291
  await tui.expectText(interpolate(text, world.vars));
1347
1292
  });
1348
- Then("I should see {string} in the terminal", { tags: "@tui" }, async ({ tui, world }, text) => {
1293
+ Then("I should see {string} in the terminal", async ({ tui, world }, text) => {
1349
1294
  await tui.expectText(interpolate(text, world.vars));
1350
1295
  });
1351
- Then("I should see text {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1352
- await tui.expectText(interpolate(text, world.vars));
1353
- });
1354
- Then("I should not see {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1296
+ Then("I should not see {string}", async ({ tui, world }, text) => {
1355
1297
  await tui.expectNotText(interpolate(text, world.vars));
1356
1298
  });
1357
- Then("the screen should contain {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1299
+ Then("the screen should contain {string}", async ({ tui, world }, text) => {
1358
1300
  await tui.assertScreenContains(interpolate(text, world.vars));
1359
1301
  });
1360
- Then("the screen should match pattern {string}", { tags: "@tui" }, async ({ tui }, pattern) => {
1302
+ Then("the screen should match pattern {string}", async ({ tui }, pattern) => {
1361
1303
  await tui.assertScreenMatches(new RegExp(pattern));
1362
1304
  });
1363
- When("I wait for {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1305
+ When("I wait for {string}", async ({ tui, world }, text) => {
1364
1306
  await tui.waitForText(interpolate(text, world.vars));
1365
1307
  });
1366
1308
  When(
1367
1309
  "I wait for {string} for {int} seconds",
1368
- { tags: "@tui" },
1369
1310
  async ({ tui, world }, text, seconds) => {
1370
1311
  await tui.waitForText(interpolate(text, world.vars), { timeout: seconds * 1e3 });
1371
1312
  }
1372
1313
  );
1373
- When("I wait {int} seconds", { tags: "@tui" }, async ({ tui }, seconds) => {
1314
+ When("I wait {int} seconds", async ({ tui }, seconds) => {
1374
1315
  await tui.waitSeconds(seconds);
1375
1316
  });
1376
- Then("the screen should match snapshot {string}", { tags: "@tui" }, async ({ tui }, name) => {
1317
+ Then("the screen should match snapshot {string}", async ({ tui }, name) => {
1377
1318
  const result = await tui.matchSnapshot(name);
1378
1319
  if (!result.pass) {
1379
1320
  throw new Error(`Snapshot "${name}" mismatch:
1380
1321
  ${result.diff || "No diff available"}`);
1381
1322
  }
1382
1323
  });
1383
- Then("I take a snapshot named {string}", { tags: "@tui" }, async ({ tui }, name) => {
1324
+ Then("I take a snapshot named {string}", async ({ tui }, name) => {
1384
1325
  await tui.takeSnapshot(name);
1385
1326
  });
1386
- When("I clear the terminal", { tags: "@tui" }, async ({ tui }) => {
1327
+ When("I clear the terminal", async ({ tui }) => {
1387
1328
  await tui.clear();
1388
1329
  });
1389
- When("I resize the terminal to {int}x{int}", { tags: "@tui" }, async ({ tui }, cols, rows) => {
1330
+ When("I resize the terminal to {int}x{int}", async ({ tui }, cols, rows) => {
1390
1331
  await tui.resize({ cols, rows });
1391
1332
  });
1392
1333
  }
@@ -1395,25 +1336,25 @@ ${result.diff || "No diff available"}`);
1395
1336
  import { createBdd as createBdd15 } from "playwright-bdd";
1396
1337
  function registerTuiWizardSteps(test) {
1397
1338
  const { Given, When, Then } = createBdd15(test);
1398
- When("I navigate down {int} times", { tags: "@tui" }, async ({ tui }, times) => {
1339
+ When("I navigate down {int} times", async ({ tui }, times) => {
1399
1340
  for (let i = 0; i < times; i++) {
1400
1341
  await tui.pressKey("down");
1401
1342
  }
1402
1343
  });
1403
- When("I navigate up {int} times", { tags: "@tui" }, async ({ tui }, times) => {
1344
+ When("I navigate up {int} times", async ({ tui }, times) => {
1404
1345
  for (let i = 0; i < times; i++) {
1405
1346
  await tui.pressKey("up");
1406
1347
  }
1407
1348
  });
1408
- When("I navigate to {string} and select", { tags: "@tui" }, async ({ tui, world }, option) => {
1349
+ When("I navigate to {string} and select", async ({ tui, world }, option) => {
1409
1350
  const target = interpolate(option, world.vars);
1410
1351
  await tui.waitForText(target);
1411
1352
  await tui.pressKey("enter");
1412
1353
  });
1413
- When("I go back", { tags: "@tui" }, async ({ tui }) => {
1354
+ When("I go back", async ({ tui }) => {
1414
1355
  await tui.pressKey("escape");
1415
1356
  });
1416
- When("I fill the form:", { tags: "@tui" }, async ({ tui, world }, dataTable) => {
1357
+ When("I fill the TUI form:", async ({ tui, world }, dataTable) => {
1417
1358
  const rows = dataTable.hashes();
1418
1359
  for (const row of rows) {
1419
1360
  const field = interpolate(row.field || row.Field, world.vars);
@@ -1422,21 +1363,21 @@ function registerTuiWizardSteps(test) {
1422
1363
  await tui.pressKey("tab");
1423
1364
  }
1424
1365
  });
1425
- When("I submit the form", { tags: "@tui" }, async ({ tui }) => {
1366
+ When("I submit the form", async ({ tui }) => {
1426
1367
  await tui.pressKey("enter");
1427
1368
  });
1428
- When("I submit the form with ctrl+s", { tags: "@tui" }, async ({ tui }) => {
1369
+ When("I submit the form with ctrl+s", async ({ tui }) => {
1429
1370
  await tui.pressKey("s", { ctrl: true });
1430
1371
  });
1431
- When("I select menu item {string}", { tags: "@tui" }, async ({ tui, world }, item) => {
1372
+ When("I select menu item {string}", async ({ tui, world }, item) => {
1432
1373
  const target = interpolate(item, world.vars);
1433
1374
  await tui.waitForText(target);
1434
1375
  await tui.selectOption(target);
1435
1376
  });
1436
- When("I open the menu", { tags: "@tui" }, async ({ tui }) => {
1377
+ When("I open the menu", async ({ tui }) => {
1437
1378
  await tui.pressKey("m", { alt: true });
1438
1379
  });
1439
- When("I select from dropdown {string} value {string}", { tags: "@tui" }, async ({ tui, world }, dropdown, value) => {
1380
+ When("I select from dropdown {string} value {string}", async ({ tui, world }, dropdown, value) => {
1440
1381
  const dropdownLabel = interpolate(dropdown, world.vars);
1441
1382
  const selectedValue = interpolate(value, world.vars);
1442
1383
  await tui.waitForText(dropdownLabel);
@@ -1444,25 +1385,25 @@ function registerTuiWizardSteps(test) {
1444
1385
  await tui.waitForText(selectedValue);
1445
1386
  await tui.pressKey("enter");
1446
1387
  });
1447
- When("I press ctrl+{word}", { tags: "@tui" }, async ({ tui }, key) => {
1388
+ When(/^I press ctrl\+([^+\s]+)$/, async ({ tui }, key) => {
1448
1389
  await tui.pressKey(key, { ctrl: true });
1449
1390
  });
1450
- When("I press alt+{word}", { tags: "@tui" }, async ({ tui }, key) => {
1391
+ When("I press alt+{word}", async ({ tui }, key) => {
1451
1392
  await tui.pressKey(key, { alt: true });
1452
1393
  });
1453
- When("I press shift+{word}", { tags: "@tui" }, async ({ tui }, key) => {
1394
+ When("I press shift+{word}", async ({ tui }, key) => {
1454
1395
  await tui.pressKey(key, { shift: true });
1455
1396
  });
1456
- When("I press ctrl+shift+{word}", { tags: "@tui" }, async ({ tui }, key) => {
1397
+ When("I press ctrl+shift+{word}", async ({ tui }, key) => {
1457
1398
  await tui.pressKey(key, { ctrl: true, shift: true });
1458
1399
  });
1459
- When("I quit the application", { tags: "@tui" }, async ({ tui }) => {
1400
+ When("I quit the application", async ({ tui }) => {
1460
1401
  await tui.pressKey("q");
1461
1402
  });
1462
- When("I force quit the application", { tags: "@tui" }, async ({ tui }) => {
1403
+ When("I force quit the application", async ({ tui }) => {
1463
1404
  await tui.pressKey("c", { ctrl: true });
1464
1405
  });
1465
- Then("line {int} should contain {string}", { tags: "@tui" }, async ({ tui, world }, lineNum, text) => {
1406
+ Then("line {int} should contain {string}", async ({ tui, world }, lineNum, text) => {
1466
1407
  const lines = await tui.getScreenLines();
1467
1408
  const expectedText = interpolate(text, world.vars);
1468
1409
  const lineIndex = lineNum - 1;
@@ -1474,7 +1415,7 @@ function registerTuiWizardSteps(test) {
1474
1415
  Actual: "${lines[lineIndex]}"`);
1475
1416
  }
1476
1417
  });
1477
- Then("the first line should contain {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1418
+ Then("the first line should contain {string}", async ({ tui, world }, text) => {
1478
1419
  const lines = await tui.getScreenLines();
1479
1420
  const expectedText = interpolate(text, world.vars);
1480
1421
  if (!lines[0]?.includes(expectedText)) {
@@ -1482,7 +1423,7 @@ Actual: "${lines[lineIndex]}"`);
1482
1423
  Actual: "${lines[0]}"`);
1483
1424
  }
1484
1425
  });
1485
- Then("the last line should contain {string}", { tags: "@tui" }, async ({ tui, world }, text) => {
1426
+ Then("the last line should contain {string}", async ({ tui, world }, text) => {
1486
1427
  const lines = await tui.getScreenLines();
1487
1428
  const expectedText = interpolate(text, world.vars);
1488
1429
  const lastLine = lines[lines.length - 1] || "";
@@ -1491,49 +1432,49 @@ Actual: "${lines[0]}"`);
1491
1432
  Actual: "${lastLine}"`);
1492
1433
  }
1493
1434
  });
1494
- Then("I should see all of:", { tags: "@tui" }, async ({ tui, world }, dataTable) => {
1435
+ Then("I should see all of:", async ({ tui, world }, dataTable) => {
1495
1436
  const rows = dataTable.raw();
1496
1437
  for (const row of rows) {
1497
1438
  const text = interpolate(row[0], world.vars);
1498
1439
  await tui.expectText(text);
1499
1440
  }
1500
1441
  });
1501
- Then("I should not see any of:", { tags: "@tui" }, async ({ tui, world }, dataTable) => {
1442
+ Then("I should not see any of:", async ({ tui, world }, dataTable) => {
1502
1443
  const rows = dataTable.raw();
1503
1444
  for (const row of rows) {
1504
1445
  const text = interpolate(row[0], world.vars);
1505
1446
  await tui.expectNotText(text);
1506
1447
  }
1507
1448
  });
1508
- When("I capture the screen", { tags: "@tui" }, async ({ tui, world }) => {
1449
+ When("I capture the screen", async ({ tui, world }) => {
1509
1450
  const capture = await tui.captureScreen();
1510
1451
  world.vars["lastScreenCapture"] = capture.text;
1511
1452
  });
1512
- Then("I print the screen", { tags: "@tui" }, async ({ tui }) => {
1453
+ Then("I print the screen", async ({ tui }) => {
1513
1454
  const text = await tui.getScreenText();
1514
1455
  console.log("=== Screen Content ===");
1515
1456
  console.log(text);
1516
1457
  console.log("======================");
1517
1458
  });
1518
- When("I execute command {string}", { tags: "@tui" }, async ({ tui, world }, command) => {
1459
+ When("I execute command {string}", async ({ tui, world }, command) => {
1519
1460
  const cmd = interpolate(command, world.vars);
1520
1461
  await tui.typeText(cmd);
1521
1462
  await tui.pressKey("enter");
1522
1463
  });
1523
- When("I run {string}", { tags: "@tui" }, async ({ tui, world }, command) => {
1464
+ When("I run {string}", async ({ tui, world }, command) => {
1524
1465
  const cmd = interpolate(command, world.vars);
1525
1466
  await tui.typeText(cmd);
1526
1467
  await tui.pressKey("enter");
1527
1468
  });
1528
- When("I confirm the dialog", { tags: "@tui" }, async ({ tui }) => {
1469
+ When("I confirm the dialog", async ({ tui }) => {
1529
1470
  await tui.typeText("y");
1530
1471
  await tui.pressKey("enter");
1531
1472
  });
1532
- When("I cancel the dialog", { tags: "@tui" }, async ({ tui }) => {
1473
+ When("I cancel the dialog", async ({ tui }) => {
1533
1474
  await tui.typeText("n");
1534
1475
  await tui.pressKey("enter");
1535
1476
  });
1536
- When("I dismiss the dialog", { tags: "@tui" }, async ({ tui }) => {
1477
+ When("I dismiss the dialog", async ({ tui }) => {
1537
1478
  await tui.pressKey("escape");
1538
1479
  });
1539
1480
  }