{"version":3,"file":"TestDriver.mjs","sources":["../../src/UNSAFE_Driver/TestDriver.ts"],"sourcesContent":["import { ElementLocator } from '../UNSAFE_Locators';\nimport { type WaitForOptions, waitFor_internal } from './waitFor';\n/**\n * A TestDriver implements the platform-specific commands needed for testing\n * with adapters.\n */\nexport interface TestDriver {\n  /**\n   * Click on the given TestElement\n   * @param element The TestElement on which to click\n   */\n  click(element: TestElement, options?: ClickOptions): Promise<void>;\n  /**\n   * Execute a script in the browser environment.\n   * Note that if passing a TestElement as an argument, you must first call {@link unwrapElement}\n   * on it to pass the driver-specific element to the script.\n   * @example\n   * const testEl = await this.getElement();\n   * await driver.executeScript<number>((el: HTMLElement) => el.clientHeight), unwrapElement(testEl));\n   *\n   * @param script The script to execute\n   * @param args Any arguments to pass to the script. Access each argument through\n   * the <code>arguments</code> array.\n   */\n  executeScript<T>(script: string | ((...args: any) => T), ...args: any): Promise<T>;\n  /**\n   * Find an element in the browser environment that matches the given ElementLocator.\n   * If an element doesn't exist, this method will wait up to the timeout defined by\n   * {@link getTimeouts().elementExistsTimeout}\n   * This method throws an exception if no matching elements are found.\n   * @param locator\n   */\n  waitForElement(locator: ElementLocator): Promise<TestElement>;\n  /**\n   * Find elements in the browser environment matching the given ElementLocator. If no\n   * matching elements are found, return a blank array.\n   * @param locator\n   */\n  waitForElements(locator: ElementLocator): Promise<TestElement[]>;\n  /**\n   * Send text as keystrokes to the browser. If modifier keys are used, all key parameters in the\n   * sequence will be combined into a single chord.\n   * @param element The element to receive the keystrokes\n   * @param text The text value to send, or an array of KeyMap strings to send as a chord of keys\n   */\n  sendKeys(element: TestElement, ...text: (string | KeyType)[]): Promise<void>;\n  /**\n   * Unwrap the given TestElement into its driver-specific element\n   * @param element\n   */\n  unwrapElement<T>(element: TestElement): T;\n}\n\n/**\n * A base class for implementing the TestDriver interface. Platform-specific TestDrivers should\n * extend this class to inherit behavior for waiting on conditions.\n */\nexport abstract class TestDriverBase implements TestDriver {\n  /**\n   * Wait for a condition to pass.\n   * @param callback The function to run. Return truthy to stop the wait; anything else will retry\n   * the callback. The truthy return value of the callback will be returned to the caller.\n   * @param options Options for wait time/interval\n   * @returns A Promise resolving to the returned value from the callback\n   */\n  async waitFor<T>(callback: () => T | Promise<T>, options?: WaitForOptions) {\n    return waitFor_internal(callback, options);\n  }\n  abstract click(element: TestElement, options?: ClickOptions): Promise<void>;\n  abstract executeScript<T>(script: string | ((...args: any) => T), ...args: any): Promise<T>;\n  abstract waitForElement(locator: ElementLocator): Promise<TestElement>;\n  abstract waitForElements(locator: ElementLocator): Promise<TestElement[]>;\n  abstract sendKeys(element: TestElement, ...text: (string | KeyType)[]): Promise<void>;\n  abstract unwrapElement<T>(element: TestElement): T;\n}\n\n/**\n * A TestElement represents the DOM element in the browser environment. This interface\n * is used by test adapters to work with elements without being bound to a specific\n * platform implementation.\n */\nexport interface TestElement {\n  /**\n   * Find an element in the browser environment that matches the given ElementLocator.\n   * This method should throw an exception if no matching elements are found.\n   * @param locator\n   */\n  waitForElement(locator: ElementLocator): Promise<TestElement>;\n  /**\n   * Find elements in the browser environment matching the given ElementLocator. If no\n   * matching elements are found, return a blank array.\n   * @param locator\n   */\n  waitForElements(locator: ElementLocator): Promise<TestElement[]>;\n  /**\n   * Get the element's attribute value from the given attrName.\n   * @param attrName\n   */\n  getAttribute(attrName: string): Promise<string | null>;\n}\n\nconst ModifierKeys = {\n  ALT: { key: 'ALT' },\n  CONTROL: { key: 'CONTROL' },\n  CONTROL_COMMAND: { key: 'CONTROL_COMMAND' },\n  SHIFT: { key: 'SHIFT' }\n} as const;\n\nexport type ClickOptions = {\n  modifiers?: (typeof ModifierKeys)[keyof typeof ModifierKeys][];\n};\n\nexport const Keys = {\n  ...ModifierKeys,\n  BACKSPACE: { key: 'BACKSPACE' },\n  TAB: { key: 'TAB' },\n  ENTER: { key: 'ENTER' },\n  ESCAPE: { key: 'ESCAPE' },\n  PAGE_UP: { key: 'PAGE_UP' },\n  PAGE_DOWN: { key: 'PAGE_DOWN' },\n  END: { key: 'END' },\n  HOME: { key: 'HOME' },\n  ARROW_LEFT: { key: 'ARROW_LEFT' },\n  ARROW_UP: { key: 'ARROW_UP' },\n  ARROW_RIGHT: { key: 'ARROW_RIGHT' },\n  ARROW_DOWN: { key: 'ARROW_DOWN' },\n  DELETE: { key: 'DELETE' },\n\n  F1: { key: 'F1' },\n  F2: { key: 'F2' },\n  F3: { key: 'F3' },\n  F4: { key: 'F4' },\n  F5: { key: 'F5' },\n  F6: { key: 'F6' },\n  F7: { key: 'F7' },\n  F8: { key: 'F8' },\n  F9: { key: 'F9' },\n  F10: { key: 'F10' },\n  F11: { key: 'F11' },\n  F12: { key: 'F12' }\n} as const;\n\ntype KeysType = Record<keyof typeof Keys, { key: string }>;\nexport type KeyType = KeysType[keyof KeysType];\n\nlet _driver: TestDriver;\n\n/**\n * Set the TestDriver instance to be used for testing. This method should be called by\n * tests during setup, before calling any test adapter methods.\n *\n * @param driver The TestDriver instance\n */\nexport function setTestDriver(driver: TestDriver) {\n  _driver = driver;\n}\n\n/**\n * Get the configured TestDriver instance to be used for testing. This method should\n * only be called by test adapters to interact with the browser environment.\n *\n * @returns The TestDriver instance\n */\nexport function getTestDriver() {\n  if (!_driver) {\n    throw Error('Driver has not been set. Call setTestDriver()');\n  }\n  return _driver;\n}\n\n/**\n * Unwrap the given TestElement into its driver-specific element\n * @param element\n */\nexport function unwrapElement(element: TestElement) {\n  return getTestDriver().unwrapElement(element);\n}\n"],"names":[],"mappings":";;AAqDA;;;AAGG;MACmB,cAAc,CAAA;AAClC;;;;;;AAMG;AACH,IAAA,MAAM,OAAO,CAAI,QAA8B,EAAE,OAAwB,EAAA;AACvE,QAAA,OAAO,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;KAC5C;AAOF,CAAA;AA2BD,MAAM,YAAY,GAAG;AACnB,IAAA,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;AACnB,IAAA,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE;AAC3B,IAAA,eAAe,EAAE,EAAE,GAAG,EAAE,iBAAiB,EAAE;AAC3C,IAAA,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;CACf,CAAC;AAME,MAAA,IAAI,GAAG;AAClB,IAAA,GAAG,YAAY;AACf,IAAA,SAAS,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE;AAC/B,IAAA,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;AACnB,IAAA,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;AACvB,IAAA,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;AACzB,IAAA,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE;AAC3B,IAAA,SAAS,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE;AAC/B,IAAA,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;AACnB,IAAA,IAAI,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;AACrB,IAAA,UAAU,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE;AACjC,IAAA,QAAQ,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE;AAC7B,IAAA,WAAW,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE;AACnC,IAAA,UAAU,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE;AACjC,IAAA,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;AAEzB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;AACjB,IAAA,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;AACnB,IAAA,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;AACnB,IAAA,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;EACV;AAKX,IAAI,OAAmB,CAAC;AAExB;;;;;AAKG;AACG,SAAU,aAAa,CAAC,MAAkB,EAAA;IAC9C,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC;AAED;;;;;AAKG;SACa,aAAa,GAAA;IAC3B,IAAI,CAAC,OAAO,EAAE;AACZ,QAAA,MAAM,KAAK,CAAC,+CAA+C,CAAC,CAAC;KAC9D;AACD,IAAA,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;AAGG;AACG,SAAU,aAAa,CAAC,OAAoB,EAAA;AAChD,IAAA,OAAO,aAAa,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AAChD;;;;"}