Skip to content

Commit 9da119c

Browse files
committed
.
1 parent f70d24a commit 9da119c

File tree

3 files changed

+24
-32
lines changed

3 files changed

+24
-32
lines changed

tests/bdd/features/login.feature

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ Feature: Login flow
22

33
Scenario: Sign in and land on Catalog
44
Given I am on "/signin"
5-
When I click the "Okta" button
5+
When I click on the "Okta" button
66
Then I should be on "/catalog"
77
And I should see a heading "MCP Server Catalog"
88

9+
Scenario: Log out from Catalog
10+
Given I am on "/signin"
11+
When I click on the "Okta" button
12+
Then I should be on "/catalog"
13+
When I click on the "Test User" button
14+
And I click on the "Sign out" menu item
15+
Then I should be on "/signin"

tests/bdd/steps/global.steps.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ Given("I am on {string}", async function (this: PlaywrightWorld, path: string) {
66
await this.page.goto(`${this.baseUrl}${path}`);
77
});
88

9-
// Generic click step using a custom {role} parameter type
9+
// Generic click step using the {role} parameter type (canonical phrases only)
1010
When(
11-
'I click the "{string}" {role}',
11+
"I click on the {string} {role}",
1212
async function (this: PlaywrightWorld, label: string, role: AriaRole) {
1313
await this.page.getByRole(role, { name: label }).click();
1414
},

tests/bdd/support/parameter-types.ts

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,23 @@
11
import { defineParameterType } from "@cucumber/cucumber";
22
import type { AriaRole } from "@playwright/test";
3-
import {
4-
allowedRolePhrases,
5-
preferredPhraseByRole,
6-
validAriaRoles,
7-
} from "./roles.ts";
3+
import { allowedRolePhrases } from "./roles.ts";
4+
5+
// Build a tight, case-insensitive pattern from the canonical phrases
6+
const escape = (s: string) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7+
const phrases = Object.keys(allowedRolePhrases).map(escape).join("|");
8+
// Important: do not anchor (no ^ or $). Cucumber composes parameter regexps
9+
// into a larger expression; anchors can prevent proper matching.
10+
const rolePattern = new RegExp(`(?:${phrases})`);
811

912
defineParameterType({
1013
name: "role",
11-
// Match human-written role text, e.g., "menu item", "radio button", "checkbox"
12-
regexp: /[A-Za-z ][A-Za-z -]*/,
14+
// keep snippets focused on canonical phrases in feature files
15+
useForSnippets: false,
16+
regexp: rolePattern,
1317
transformer: (text: string): AriaRole => {
14-
const input = text.trim().toLowerCase();
15-
16-
// Accept only canonical phrases to reduce variants
17-
const canonical = allowedRolePhrases[input];
18-
if (canonical) {
19-
return canonical;
20-
}
21-
22-
// If user provided an ARIA role directly, recommend the canonical phrase
23-
if (validAriaRoles.has(input)) {
24-
const role = input as AriaRole;
25-
const preferred = preferredPhraseByRole[role];
26-
if (preferred && preferred !== input) {
27-
throw new Error(
28-
`Use canonical role phrase "${preferred}" instead of "${input}".`,
29-
);
30-
}
31-
// Role equals its canonical phrase (e.g., "button", "link", "checkbox")
32-
return role;
33-
}
34-
35-
// Helpful error with allowed phrases
18+
const key = text.trim().toLowerCase();
19+
const role = allowedRolePhrases[key];
20+
if (role) return role;
3621
const examples = Object.keys(allowedRolePhrases).slice(0, 10).join(", ");
3722
throw new Error(
3823
`Unknown role phrase "${text}". Use one of the canonical phrases (e.g., ${examples} ...).`,

0 commit comments

Comments
 (0)