UNPKG

playwright-json-runner

Version:

Extends Playwright to run tests using JSON-based test definitions.

1 lines 40.4 kB
{"version":3,"sources":["../src/locator-actions.ts","../src/defaults/action-type-handlers.ts","../src/defaults/getter-setter-rules.ts","../src/defaults/getter-strategies.ts","../src/defaults/setter-strategies.ts","../src/locator-resolver.ts","../src/defaults/locator-strategies.ts","../src/config.ts","../src/runner.ts"],"names":["config","xpath","locatorStrategies","error"],"mappings":"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","file":"chunk-CLGBQMKP.mjs","sourcesContent":["import { Locator } from \"playwright\";\nimport { JSDOM } from \"jsdom\";\nimport { getConfiguration, RuleMatch, Configuration} from \"./config\";\n\n\n/**\n * Finds the best matching locator and sets its value.\n * @param locator Locator representing the field\n * @param value Value to be set.\n * @param waitSeconds Timeout in seconds (default: 30s).\n */\nexport async function setLocatorValue(locator: Locator, value: string|undefined): Promise<void> {\n const html = await locator.evaluate(el => el.outerHTML);\n const config = getConfiguration();\n const ruleMatch= getRuleMatch(html, config)\n\n if (ruleMatch && config.setterStrategies[ruleMatch.id]) {\n const targetLocator = ruleMatch.matchedChild && ruleMatch.xpath? locator.locator(ruleMatch.xpath): locator\n return await config.setterStrategies[ruleMatch.id]({locator: targetLocator, ruleMatch, value});\n }\n \n throw new Error(`❌ Couldn't find a rule match for on element ${locator} \\b html: ${html}`);\n}\n\n/**\n * Finds the best matching locator and gets its value.\n * @param locator Locator representing the field\n * @param value Value to be set.\n * @param waitSeconds Timeout in seconds (default: 30s).\n */\nexport async function getLocatorValue(locator: Locator): Promise<string|null> {\n const html = await locator.evaluate(el => el.outerHTML);\n const config = getConfiguration();\n const ruleMatch= getRuleMatch(html, config)\n \n if (ruleMatch && config.getterStrategies[ruleMatch.id]) {\n const targetLocator = ruleMatch.matchedChild && ruleMatch.xpath? locator.locator(ruleMatch.xpath): locator\n return await config.getterStrategies[ruleMatch.id]({locator: targetLocator, ruleMatch});\n }\n \n throw new Error(`❌ Couldn't find a rule match for on element ${locator} \\b html: ${html}`);\n}\n\nfunction getRuleMatch(html: string, config: Configuration): RuleMatch | null {\n const { document } = new JSDOM(html).window;\n const element = document.body; \n if (!element) return null;\n let xpathMatch = undefined;\n let matchedChild = undefined\n\n const xpath = (xpath: string) : boolean =>\n {\n // XPathResult.FIRST_ORDERED_NODE_TYPE = 9\n const result = document.evaluate(xpath, document, null, 9, null);\n const matchedElement = result.singleNodeValue;\n if(matchedElement) { \n xpathMatch = xpath;\n matchedChild = element.firstElementChild !==matchedElement\n return true; \n }\n \n return false\n }\n \n for (const [id, condition] of Object.entries(config.rules)) {\n try{\n if (condition({ document: document, element: element, xpathEval: xpath})) {\n return {id, xpath: xpathMatch, matchedChild: matchedChild??false} as RuleMatch;\n }\n }\n catch(err:any)\n {\n console.error(\"error executing condition: \", id)\n throw err;\n }\n }\n\n return null; // No match found\n}\n","import { expect } from \"playwright/test\";\nimport { ActionTypeHandler } from \"../config\";\nimport { setLocatorValue, getLocatorValue } from \"../locator-actions\";\nimport { ActionType } from \"src/schemas/test-action\";\n\n\nconst actionTypeHandlers : Record<ActionType, ActionTypeHandler> = {\n \"sleep\": async (_, {value})=>{\n \n },\n \"navigate\": async (_, { value }) => {\n if (value) {\n console.log(`Navigating to ${value}`);\n \n }\n else\n {\n throw new Error(\"The 'navigate' action requires a 'url' property.\");\n }\n },\n \"setfieldvalue\": async (locator, { value }) => {\n if (!locator) {\n throw new Error(\"The 'setFieldValue' action requires a 'locator' property.\");\n }\n if (value === undefined || value === null) {\n throw new Error(\"The 'setFieldValue' action requires a non-null 'value' property.\");\n }\n await setLocatorValue(locator, value);\n },\n \"click\": async (locator) => {\n if (locator) {\n await locator.click();\n }\n else\n {\n throw new Error(\"The 'click' action requires a 'locator' or 'selector' property.\");\n }\n },\n \"assertFieldValueEquals\": async (locator, { value }) => {\n if (!locator) {\n throw new Error(\"The 'setFieldValue' action requires a 'locator' property.\");\n }\n if (value === undefined || value === null) {\n throw new Error(\"The 'setFieldValue' action requires a non-null 'value' property.\");\n }\n const actual = await getLocatorValue(locator);\n expect(actual).toBe(value);\n \n },\n \"assertFieldValueContains\": async (locator, { value }) => {\n if (!locator) {\n throw new Error(\"The 'setFieldValue' action requires a 'locator' property.\");\n }\n if (value === undefined || value === null) {\n throw new Error(\"The 'setFieldValue' action requires a non-null 'value' property.\");\n }\n const actual = await getLocatorValue(locator);\n expect(actual).toContain(value); \n },\n \"assertElementExists\": async (locator) => {\n await expect(locator).toBeAttached(); \n },\n \"expect\": async (locator, { value, playwrightFunction }) => {\n if (!locator) {\n throw new Error(\"The 'expect' action requires a 'locator' property.\");\n }\n \n if (!value) {\n throw new Error(\"The 'expect' action requires a non-null 'value' property.\");\n }\n \n if (!playwrightFunction) {\n throw new Error(\"The 'expect' action requires an 'playwrightFunction' property.\");\n }\n \n if (typeof (expect(locator) as any)[playwrightFunction] !== 'function') {\n throw new Error(`Invalid 'playwrightFunction': '${playwrightFunction}' is not a valid Playwright assertion.`);\n }\n await (expect(locator) as any)[playwrightFunction](value);\n\n }\n}\n\nexport default actionTypeHandlers;","import { RuleKeys, RuleType } from \"../config\";\n\nconst getterSetterRules : Record<RuleKeys, RuleType> = {\n \"input.datepicker\": ({ element }) => element.matches(\".custom-datepicker\"),\n \"select\": ({ xpathEval }) => xpathEval(\"//select\"),\n \"text\": ({ xpathEval }) => xpathEval(\"//input | //textarea\"),\n}\n\n\nexport default getterSetterRules;","import { GetterStrategyType, RuleKeys } from \"../config\";\n\n//strategies used to get values in the UI (getter-setter-rules.ts determine which strategy will be used)\n\nconst getterStrategies: Record<RuleKeys, GetterStrategyType> = {\n \"input.datepicker\": async ({ locator }) => {\n return await locator.inputValue();\n },\n \"select\": async ({ locator }) => {\n const selectedOption = locator.locator('option:checked');\n return selectedOption ? await selectedOption.innerText() : '';\n },\n \"text\": async ({ locator }) => {\n return await locator.inputValue();\n }\n}\n\nexport default getterStrategies;","import { SetterStrategyType, RuleKeys } from \"../config\";\n\n//strategies used to set values in the UI (getter-setter-rules.ts determine which strategy will be used)\n\nconst setterStrategies: Record<RuleKeys, SetterStrategyType> = {\n \"select\": async ({ locator, value }) => {\n await locator.selectOption({ label: value, value: value });\n },\n \"text\": async ({ locator, value }) => {\n await locator.fill(value ?? \"\");\n },\n \"input.datepicker\": async ({ locator, value }) => {\n await locator.click(); // Open the date picker\n await locator.page().locator(`//button[text()='${value}']`).click(); // Select the date\n },\n\n}\nexport default setterStrategies;","import { Locator, Page } from \"playwright\";\nimport { LocatorStrategyParams, NestedStrategyParams, RoleStrategyParams, SelectorStrategyParams, TestIdStrategyParams, TextStrategyParams } from \"./schemas/locators/locator-parameters\";\n\nexport type LocatorStrategies =Partial< {\n selector: (page: Page, param: SelectorStrategyParams) => Promise<Locator>;\n role: (page: Page, param: RoleStrategyParams) => Promise<Locator>;\n testId: (page: Page, param: TestIdStrategyParams) => Promise<Locator>;\n text: (page: Page, param: TextStrategyParams) => Promise<Locator>;\n nested: (page: Page, param: NestedStrategyParams) => Promise<Locator>;\n} & Record<string, (page: Page, param: any) => Promise<Locator>>>; \n\nexport async function resolveLocator<T extends LocatorStrategyParams[\"type\"]>(\n locatorStrategies: LocatorStrategies,\n page: Page, \n strategy: Extract<LocatorStrategyParams, { type: T }>\n ): Promise<Locator> {\n // Get the correct handler\n const handler = locatorStrategies[strategy.type] as (\n page: Page, \n param: Extract<LocatorStrategyParams, { type: T }>\n ) => Promise<Locator>;\n \n if (!handler) {\n throw new Error(`Invalid locator strategy: ${JSON.stringify(strategy)}`);\n }\n \n // Pass the correctly inferred type to the handler\n return handler(page, strategy);\n}\n\n","import { NestedStrategyParams, RoleStrategyParams, SelectorStrategyParams, TestIdStrategyParams, TextStrategyParams } from \"src/schemas/locators/locator-parameters\";\nimport { LocatorStrategies, resolveLocator } from \"../locator-resolver\";\n\nconst locatorStrategies: LocatorStrategies = {\n selector: async (page, strategy: SelectorStrategyParams) => \n page.locator(strategy.value),\n\n role: async (page, strategy: RoleStrategyParams) => \n page.getByRole(strategy.value.role, strategy.value.options ?? {}),\n\n testId: async (page, strategy: TestIdStrategyParams) => \n page.getByTestId(strategy.value),\n\n text: async (page, strategy: TextStrategyParams) => \n page.getByText(strategy.value),\n\n nested: async (page, strategy: NestedStrategyParams) => {\n const parentLocator = await resolveLocator(locatorStrategies, page, strategy.parent);\n const childLocator = await resolveLocator(locatorStrategies, page, strategy.child);\n return parentLocator.locator(childLocator);\n },\n};\nexport default locatorStrategies\n\n","import { cosmiconfigSync } from \"cosmiconfig\";\nimport { Locator } from \"playwright\";\nimport actionTypeHandlers from \"./defaults/action-type-handlers\";\nimport getterSetterRules from \"./defaults/getter-setter-rules\";\nimport getterStrategies from \"./defaults/getter-strategies\";\nimport setterStrategies from \"./defaults/setter-strategies\";\nimport locatorStrategies from \"./defaults/locator-strategies\";\nimport { ActionType, TestAction } from \"./schemas/test-action\";\nimport { LocatorStrategies } from \"./locator-resolver\";\n\nexport const baseConfig: Configuration = {\n actionTypeHandlers: actionTypeHandlers,\n rules: getterSetterRules,\n setterStrategies: setterStrategies,\n getterStrategies: getterStrategies,\n locatorStrategies: locatorStrategies,\n jsonTestDir: 'json-tests',\n jsonTestMatch: `**\\/*.playwright.json`\n};\n\nexport type RuleKeys =\n 'input.datepicker' |\n 'select' |\n 'text';\nexport type RuleType = (params: ConditionParams) => boolean;\nexport type SetterStrategyType = (param: StrategyParam) => Promise<void>;\nexport type GetterStrategyType = (param: StrategyParam) => Promise<string | null>;\nexport type ActionTypeHandler = (locator: Locator, action: TestAction) => Promise<void>;\n\n\nexport interface RuleMatch {\n id: string\n xpath?: string,\n matchedChild: boolean\n}\nexport interface ConditionParams {\n document: Document,\n element: Element\n xpathEval: (xpath: string) => boolean\n}\nexport interface StrategyParam {\n locator: Locator,\n ruleMatch: RuleMatch\n value?: string\n}\n\n /**\n * **usage**\n * \n * \n * the below config enables you to have the following functionalities in any json test:\n * - ```locator: {type: textWaitForDom}``` within any action (because of ```locatorStrategies``` property)\n * - ```clear``` action (because of ```actionTypeHandlers``` property)\n * - ```assertClear``` action (because of ```actionTypeHandlers``` property)\n * - ```setFieldValue``` on an input that's editable using our ```setterStrategies``` entry ```myCustomInput```\n * - ```assertFieldValue``` on an input that's editable ```getterStrategies``` entry ```myCustomInput```\n * \n * \n * playwright-json.config.ts example:\n * ```\n * import { expect } from \"@playwright/test\";\n * import { extendConfig } from \"playwright-json-runner\";\n * import {getLocatorValue, setLocatorValue} from \"playwright-json-runner\"\n *\n * const userConfig = extendConfig({\n * jsonTestDir: \"json-tests\",\n * locatorStrategies: {\n * textWaitForDom: async (page, strategy) => \n * {\n * page.waitForLoadState(\"domcontentloaded\");\n * return page.getByText(strategy.value)\n * }\n * },\n * actionTypeHandlers:{ \n * \"clear\": async (locator)=>{\n * setLocatorValue(locator, \"\")\n * },\n * \"assertClear\": async (locator)=>{\n * expect(getLocatorValue(locator)).toBe(\"\")\n * }\n * },\n * //define when it applies\n * rules: {\n * \"myCustomInput\": ({ xpathEval }) => xpathEval(\"//div[@contenteditable=true\")\n * },\n * //strategy for getting the value used when actionTypeHandlers call setLocatorValue\n * getterStrategies: {\n * \"myCustomInput\": async ({locator}) => await locator.inputValue()\n * },\n * //strategy for setting the value used when actionTypeHandlers call getLoctorvalue\n * setterStrategies: {\n * \"myCustomInput\": async ({locator, value}) => await locator.fill(value??\"\")\n * }\n * \n * });\n *\n * export default userConfig;\n * ```\n * \n * then you can layout your playwright.json test like this:\n * \n * ```\n * {\n * \"driver\": \"Playwright\",\n * \"browser\": \"chrome\",\n * \"host\": \"https://www.github.com/\",\n * \"scenarios\": [\n * {\n * \"name\": \"Signup Test\",\n * \"steps\": [\n * {\n * \"description\": \"Navigate to create account\",\n * \"actions\": [\n * {\n * \"type\": \"clear\",\n * \"selector\":\"[id='name']\"\n * },\n * {\n * \"type\": \"assertclear\",\n * \"selector\":\"[id='name']\"\n * },\n * {\n * \"type\": \"click\",\n * \"locator\":{type: \"textWaitForDom\": value: \"Check Box Label\"}\n * },\n * {\n * \"type\": \"setFieldValue\",\n * \"selector\": \"//div[@id='blog-body' and contenteditable=true]\"\n * \"value\": \"some blog writing\"\n * },\n * {\n * \"type\": \"assertFieldValueEquals\",\n * \"selector\": \"//div[@id='blog-body' and contenteditables=true]\"\n * \"value\": \"some blog writing\"\n * } \n * ]\n * }\n * ]\n * }\n * ]\n * }\n * ```\n */\nexport function extendConfig(extensions: Partial<Configuration>): Configuration {\n return {\n ...baseConfig,\n ...extensions, // Merge top-level properties\n\n locatorStrategies: {\n ...baseConfig.locatorStrategies,\n ...extensions.locatorStrategies ?? {} // Merge objects\n },\n actionTypeHandlers: {\n ...baseConfig.actionTypeHandlers,\n ...extensions.actionTypeHandlers ?? {} // Merge objects\n },\n rules: {\n ...baseConfig.rules,\n ...extensions.rules ?? {} // Merge objects\n },\n getterStrategies: {\n ...baseConfig.getterStrategies,\n ...extensions.getterStrategies ?? {} // Merge objects\n },\n setterStrategies: {\n ...baseConfig.setterStrategies,\n ...extensions.setterStrategies ?? {} // Merge objects\n }\n };\n}\n\n\n\n /**\n * **usage**\n * \n * \n * the below config enables you to have the following functionalities in any json test:\n * - ```locator: {type: textWaitForDom}``` within any action (because of ```locatorStrategies``` property)\n * - ```clear``` action (because of ```actionTypeHandlers``` property)\n * - ```assertClear``` action (because of ```actionTypeHandlers``` property)\n * - ```setFieldValue``` on an input that's editable using our ```setterStrategies``` entry ```myCustomInput```\n * - ```assertFieldValue``` on an input that's editable ```getterStrategies``` entry ```myCustomInput```\n * \n * \n * playwright-json.config.ts example:\n * ```\n * import { expect } from \"@playwright/test\";\n * import { extendConfig } from \"playwright-json-runner\";\n * import {getLocatorValue, setLocatorValue} from \"playwright-json-runner\"\n *\n * const userConfig = extendConfig({\n * jsonTestDir: \"json-tests\",\n * locatorStrategies: {\n * textWaitForDom: async (page, strategy) => \n * {\n * page.waitForLoadState(\"domcontentloaded\");\n * return page.getByText(strategy.value)\n * }\n * },\n * actionTypeHandlers:{ \n * \"clear\": async (locator)=>{\n * setLocatorValue(locator, \"\")\n * },\n * \"assertClear\": async (locator)=>{\n * expect(getLocatorValue(locator)).toBe(\"\")\n * }\n * },\n * //define when it applies\n * rules: {\n * \"myCustomInput\": ({ xpathEval }) => xpathEval(\"//div[@contenteditable=true\")\n * },\n * //strategy for getting the value used when actionTypeHandlers call setLocatorValue\n * getterStrategies: {\n * \"myCustomInput\": async ({locator}) => await locator.inputValue()\n * },\n * //strategy for setting the value used when actionTypeHandlers call getLoctorvalue\n * setterStrategies: {\n * \"myCustomInput\": async ({locator, value}) => await locator.fill(value??\"\")\n * }\n * \n * });\n *\n * export default userConfig;\n * ```\n * \n * then you can layout your playwright.json test like this:\n * \n * ```\n * {\n * \"driver\": \"Playwright\",\n * \"browser\": \"chrome\",\n * \"host\": \"https://www.github.com/\",\n * \"scenarios\": [\n * {\n * \"name\": \"Signup Test\",\n * \"steps\": [\n * {\n * \"description\": \"Navigate to create account\",\n * \"actions\": [\n * {\n * \"type\": \"clear\",\n * \"selector\":\"[id='name']\"\n * },\n * {\n * \"type\": \"assertclear\",\n * \"selector\":\"[id='name']\"\n * },\n * {\n * \"type\": \"click\",\n * \"locator\":{type: \"textWaitForDom\": value: \"Check Box Label\"}\n * },\n * {\n * \"type\": \"setFieldValue\",\n * \"selector\": \"//div[@id='blog-body' and contenteditable=true]\"\n * \"value\": \"some blog writing\"\n * },\n * {\n * \"type\": \"assertFieldValueEquals\",\n * \"selector\": \"//div[@id='blog-body' and contenteditables=true]\"\n * \"value\": \"some blog writing\"\n * } \n * ]\n * }\n * ]\n * }\n * ]\n * }\n * ```\n */\ninterface Configuration<TActionType extends string = ActionType | string, TRuleKeys extends string = RuleKeys | string> {\n locatorStrategies: LocatorStrategies\n actionTypeHandlers: Record<TActionType, ActionTypeHandler>;\n /**\n * **What**: `xpathEval` is a function that evaluates an XPath expression within a locator's context.\n *\n * **Why**: This allows users to dynamically resolve elements **relative to a known locator**, ensuring more flexible and adaptable test strategies.\n *\n * **How It Works**:\n * - The **locator** points to an element (e.g., a `div` with `id=\"name\"`).\n * - `xpathEval` runs an **XPath query within that element's context**.\n * - xpathEval loads the locator's HTML upfront, then runs the XPath query against it. this allows lighting fast checking of the xpath query\n *\n * ---\n *\n * **📌 Example Scenario**\n *\n * **HTML Structure:**\n * ```html\n * <body>\n * <div id=\"name\">\n * <customInputTag></customInputTag>\n * </div>\n * </body>\n * ```\n *\n * **JSON Configuration (Example Action for `setFieldValue`):**\n * ```json\n * {\n * \"selector\": \"[id='name']\",\n * \"type\": \"setFieldValue\",\n * \"value\": \"first name\"\n * }\n * ```\n *\n * **📌 How `xpathEval` Works Here**\n * - The **locator** initially references the `div` (`id=\"name\"`).\n * - `xpathEval(\"//customInputTag\")` **runs inside the `div`'s context**, returning the `<customInputTag>` element.\n * - The `setFieldValue` action is **executed on `<customInputTag>`** instead of the `div` itself.\n *\n * ---\n *\n * **🚀 Why This Matters**\n * - Lets you **refine targeting** within an existing locator instead of writing full XPath queries.\n * - Avoids brittle full-document XPath lookups.\n * - Works well for **nested custom elements**.\n */\n rules: Record<TRuleKeys, RuleType>;\n /**\n * **What**: strategies for **setting** the value\n * \n * **Why** this allows the user to implement custom ways of handling setting a value\n * \n * **When**: ```actionTypeHandlers``` call ```setLocatorValue``` and rule with the **key** returns true\n * \n * **Requirement**: must add an entry in rules for it to apply \n * \n * **IMPORTANT**: rules order matters! notice how the new rule (often most complex) is defined on top, because whatever rule matches first, is the one that will be used\n * \n * usage\n *\n * ```\n * const userConfig = extendConfig({\n * rules: {\n * \"contentEditableDiv\": ({ xpathEval }) => xpathEval(\"//div[@contenteditable=true]\")\n * },\n * setterStrategies: {\n * \"myCustomInput\": async ({ locator, value }) => {\n * await locator.fill(value ?? \"\");\n * }\n * }\n * });\n * export default userConfig\n * ```\n */\n setterStrategies: Record<TRuleKeys, SetterStrategyType>;\n /**\n * \n * **What**: strategies for **getting** the value\n * \n * **Why** this allows the user to implement custom ways of handling getting a value\n * \n * **When**: ```actionTypeHandlers``` call ```getLocatorValue``` and rule with the **key** returns true\n * \n * **Requirement**: must add an entry in rules for it to apply \n * \n * **IMPORTANT**: rules order matters! notice how the new rule (often most complex) is defined on top, because whatever rule matches first, is the one that will be used\n * usage\n *\n * ```\n * \n * const userConfig = extendConfig({\n * rules: {\n * \"contentEditableDiv\": ({ xpathEval }) => xpathEval(\"//div[@contenteditable=true]\")\n * },\n * setterStrategies: {\n * \"contentEditableDiv\": async ({locator}) => await locator.inputValue()\n * }\n * });\n * export default userConfig\n * \n * ```\n */\n getterStrategies: Record<TRuleKeys, GetterStrategyType>;\n\n /**\n * Directory that will be recursively scanned for test files. Defaults to the directory of the configuration file.\n */\n jsonTestDir: string;\n /**\n * Only the files matching one of these patterns are executed as test files. Matching is performed against the\n * absolute file path. Strings are treated as glob patterns.\n *\n * By default, the runner looks for files matching the following glob pattern: `**\\/*.playwright.json`\n * This means Json files with `\".playwright.json\"` suffix, for example\n * `github.playwright.json`.\n */\n jsonTestMatch: string | RegExp;\n}\n\nexport type { Configuration }\n\n\n\n// Define the valid rule keys\n\nlet config: Configuration | undefined;\n\nexport function getConfiguration(): Configuration {\n if (config) {\n return config;\n }\n config = loadConfiguration()\n return config;\n}\n\nconst explorer = cosmiconfigSync('playwright-json', {\n searchPlaces: [\n 'playwright-json.config.ts',\n 'playwright-json.config.js',\n ],\n});\n\nexport function loadConfiguration(): Configuration {\n try {\n if(explorer)\n {\n const result = explorer.search();\n if (result && result.config) {\n return result.config || result.config.default;\n } else {\n return baseConfig;\n }\n }\n else\n {\n return baseConfig;\n }\n } catch (error) {\n console.error('❌ Failed to load user config:', error);\n return baseConfig;\n }\n}\n","import { chromium, firefox, webkit, Browser, Page } from \"playwright\";\nimport { error } from \"console\";\nimport { getConfiguration, Configuration } from \"./config\";\nimport { TestAction } from \"./schemas/test-action\";\nimport { TestScenario } from \"./schemas/test-scenario\";\nimport { TestStep } from \"./schemas/test-step\";\nimport { TestRun } from \"./schemas/test-run\";\nimport { resolveLocator } from \"./locator-resolver\";\n\nexport async function runTests(testRun: TestRun): Promise<void> {\n const config = getConfiguration();\n \n // Select browser\n const browserType = {\n chrome: chromium,\n firefox: firefox,\n webkit: webkit,\n }[testRun.browser] || chromium; // Default to Chromium\n\n const browser: Browser = await browserType.launch();\n\n console.log(`🚀 Running tests on ${testRun.host} using ${testRun.browser}`);\n\n await ExecuteTestRun(config, browser, testRun);\n\n await browser.close();\n}\n\nasync function ExecuteTestRun(config: Configuration, browser: Browser, testRun: TestRun) {\n for (const scenario of testRun.scenarios) {\n const context = await browser.newContext({baseURL: testRun.host, recordVideo: {dir:\"./videos\"}});\n const page: Page = await context.newPage();\n try{\n executeScenario(config, page, scenario);\n }\n finally{\n await context.close();\n }\n\n }\n \n}\n\nasync function executeScenario(config: Configuration, page: Page, scenario: TestScenario) {\n console.log(`📌 Executing scenario: ${scenario.label?? scenario.name}`);\n await page.goto(\"/\");\n\n for (const step of scenario.steps) {\n await executeStep(config, page, step); \n }\n \n}\n\nasync function executeStep(config: Configuration, page: Page, step: TestStep) {\n console.log(` 🛠 Step: ${step.label ?? step.description}`);\n for (const action of step.actions) {\n await executeAction(config, page, action);\n }\n}\n\nexport async function executeAction(config: Configuration, page: Page, action: TestAction) {\n\n console.log(` - 🔹 Performing action: ` + (action.label ?? `${action.type}`));\n\n if (action.type === \"navigate\") {\n await HandleActionTypeNavigate(action, page)\n return;\n }\n if (action.type === \"sleep\") {\n if(!action.value)\n {\n throw error(\"Action type: sleep must have 'value' prop in MS\")\n }\n await page.waitForTimeout(Number.parseInt(action.value));\n return;\n }\n //handle selector based action (replaces locator property in the object)\n if(action.selector)\n {\n action.locator = {\n type: \"selector\",\n value: action.selector\n }\n }\n if (!action.locator) {\n throw new Error(`Action must have a valid locator: ${JSON.stringify(action)}`);\n }\n const locator = await resolveLocator(config.locatorStrategies, page, action.locator);\n\n const handler = Object.entries(config.actionTypeHandlers).find(\n ([key]) => key.toLowerCase() === action.type.toLowerCase()\n )?.[1];\n \n if (!handler) {\n throw new Error(`No handler found for action type: ${action.type}`);\n }\n await handler(locator, action);\n}\n\n\nasync function HandleActionTypeNavigate(action: TestAction, page: Page) {\n if (action.value) {\n console.log(\"navigating to: \", action.value)\n await page.goto(action.value);\n }\n\n else {\n throw error(\"navigate action requires the url to be provided as value\");\n }\n}\n"]}