{"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"]}