puppeteer-declarations.d.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. import type { EventInitDict, EventSpy, ScreenshotDiff, ScreenshotOptions } from '@stencil/core/internal';
  2. // @ts-ignore - avoid requiring puppeteer as dependency
  3. import type { ClickOptions, HTTPResponse, Page, ScreenshotOptions as PuppeteerScreenshotOptions, WaitForOptions } from 'puppeteer';
  4. /**
  5. * This type was once exported by Puppeteer, but has since moved to an object literal in (Puppeteer’s) native types.
  6. * Re-create it here as a named type to use across multiple Stencil-related testing files.
  7. */
  8. export type PageCloseOptions = {
  9. runBeforeUnload?: boolean;
  10. };
  11. export interface NewE2EPageOptions extends WaitForOptions {
  12. url?: string;
  13. html?: string;
  14. /**
  15. * If set to `true`, Stencil will throw an error if a console error occurs
  16. */
  17. failOnConsoleError?: boolean;
  18. /**
  19. * If set to `true`, Stencil will throw an error if a network request fails
  20. */
  21. failOnNetworkError?: boolean;
  22. /**
  23. * If set to `true`, Stencil will log failing network requests
  24. * @default true
  25. */
  26. logFailingNetworkRequests?: boolean;
  27. }
  28. type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
  29. type PuppeteerPage = Omit<Page, 'bringToFront' | 'browser' | 'screenshot' | 'emulate' | 'emulateMedia' | 'frames' | 'goBack' | 'goForward' | 'isClosed' | 'mainFrame' | 'pdf' | 'reload' | 'target' | 'title' | 'viewport' | 'waitForNavigation' | 'screenshot' | 'workers' | 'addListener' | 'prependListener' | 'prependOnceListener' | 'removeAllListeners' | 'setMaxListeners' | 'getMaxListeners' | 'listeners' | 'rawListeners' | 'emit' | 'eventNames' | 'listenerCount' | '$x' | 'waitForXPath'>;
  30. export interface PageDiagnostic {
  31. type: 'error' | 'pageerror' | 'requestfailed';
  32. message?: string;
  33. location?: string;
  34. }
  35. /**
  36. * The E2EPage is a wrapper utility to Puppeteer in order to
  37. * to create easier to write and read end-to-end tests.
  38. */
  39. export interface E2EPage extends PuppeteerPage {
  40. /**
  41. * `Experimental`
  42. * Takes a screenshot of the page, then compares the current screenshot
  43. * against the master screenshot. The returned screenshot compare
  44. * results can then be used to test pixel mismatches, such as
  45. * `expect(results).toMatchScreenshot()`.
  46. */
  47. compareScreenshot(): Promise<ScreenshotDiff>;
  48. /**
  49. * `Experimental`
  50. * Takes a screenshot of the page, then compares the current screenshot
  51. * against the master screenshot. The provided `description` will be
  52. * added onto its current description, which comes from the test description.
  53. */
  54. compareScreenshot(description: string): Promise<ScreenshotDiff>;
  55. /**
  56. * `Experimental`
  57. * Takes a screenshot of the page, then compares the current screenshot
  58. * against the master screenshot. The `opts` argument can be used to
  59. * customize screenshot options.
  60. */
  61. compareScreenshot(opts: ScreenshotOptions): Promise<ScreenshotDiff>;
  62. /**
  63. * `Experimental`
  64. * Takes a screenshot of the page, then compares the current screenshot
  65. * against the master screenshot. The `description` argument will be
  66. * added onto its current description, which comes from the test description.
  67. * The `opts` argument can be used to customize screenshot options.
  68. */
  69. compareScreenshot(description: string, opts: ScreenshotOptions): Promise<ScreenshotDiff>;
  70. /**
  71. * Sets a debugger;
  72. */
  73. debugger(): Promise<void>;
  74. /**
  75. * Find an element that matches the selector, which is the same as
  76. * `document.querySelector(selector)`. Use `>>>` within the
  77. * selector to find an element within the host element's shadow root.
  78. * For example, to select the first `div` inside of the component
  79. * `my-cmp`, the call would be `page.find('my-cmp >>> div')`.
  80. * Returns `null` if an element was not found.
  81. */
  82. find(selector: FindSelector): Promise<E2EElement>;
  83. /**
  84. * Find all elements that match the selector, which is the same as
  85. * `document.querySelectorAll(selector)`. Use `>>>` within the
  86. * selector to find elements within the host element's shadow root.
  87. * For example, to select all of the `li` elements inside of the component
  88. * `my-cmp`, the call would be `page.findAll('my-cmp >>> li')`.
  89. * Returns an empty array if no elements were found.
  90. */
  91. findAll(selector: string): Promise<E2EElement[]>;
  92. /**
  93. * During an end-to-end test, a dev-server is started so `page.goto(url)` can be used
  94. * on the app being tested. Urls are always relative since the dev server provides
  95. * a localhost address. A shortcut to `page.goto(url)` is to set the `url` option
  96. * when creating a new page, such as `const page = await newE2EPage({ url })`.
  97. */
  98. goTo(url: string, options?: WaitForOptions): Promise<HTTPResponse | null>;
  99. /**
  100. * Instead of testing a url directly, html content can be mocked using
  101. * `page.setContent(html)`. A shortcut to `page.setContent(html)` is to set
  102. * the `html` option when creating a new page, such as
  103. * `const page = await newE2EPage({ html })`.
  104. */
  105. setContent(html: string, options?: WaitForOptions): Promise<void>;
  106. /**
  107. * Used to test if an event was, or was not dispatched. This method
  108. * returns a promise, that resolves with an EventSpy. The EventSpy
  109. * can be used along with `expect(spy).toHaveReceivedEvent()`,
  110. * `expect(spy).toHaveReceivedEventTimes(x)` and
  111. * `expect(spy).toHaveReceivedEventDetail({...})`.
  112. */
  113. spyOnEvent(eventName: string, selector?: 'window' | 'document'): Promise<EventSpy>;
  114. /**
  115. * Both Stencil and Puppeteer have an asynchronous architecture, which is a good thing
  116. * for performance. Since all calls are async, it's required that
  117. * `await page.waitForChanges()` is called when changes are made to components.
  118. * An error will be thrown if changes were made to a component but `waitForChanges()`
  119. * was not called.
  120. */
  121. waitForChanges(): Promise<void>;
  122. /**
  123. * Waits for the event to be received on `window`. The optional second argument
  124. * allows the listener to be set to `document` if needed.
  125. */
  126. waitForEvent(eventName: string): Promise<any>;
  127. getDiagnostics(): PageDiagnostic[];
  128. }
  129. export interface E2EPageInternal extends E2EPage {
  130. isClosed(): boolean;
  131. _e2eElements: E2EElementInternal[];
  132. _e2eEvents: Map<number, WaitForEvent>;
  133. _e2eEventIds: number;
  134. _e2eGoto(url: string, options?: Partial<WaitForOptions>): Promise<HTTPResponse | null>;
  135. _e2eClose(options?: PageCloseOptions): Promise<void>;
  136. screenshot(options?: PuppeteerScreenshotOptions): Promise<Buffer>;
  137. }
  138. export interface E2EElement {
  139. /**
  140. * Used to call a method on a component. For example, if a component
  141. * has the method `cmp.myMethod(arg1, arg2)`, calling this method
  142. * from a e2e test could be `cmp.callMethod('myMethod', arg1, arg2)`.
  143. */
  144. callMethod(methodName: string, ...methodArgs: any[]): Promise<any>;
  145. /**
  146. * Gets and sets the value of the class attribute of the e2e element.
  147. * Note that `await page.waitForChanges()` must be called before reading
  148. * the value if content has changed.
  149. */
  150. className: string;
  151. /**
  152. * Using classList is a convenient alternative to accessing an element's list
  153. * of classes as a space-delimited string via `element.className`.
  154. */
  155. classList: {
  156. /**
  157. * Add specified class values. If these classes already exist in
  158. * attribute of the element, then they are ignored.
  159. */
  160. add: (...tokens: string[]) => void;
  161. /**
  162. * Remove specified class values. Note: Removing a class that does
  163. * not exist does NOT throw an error.
  164. */
  165. remove: (...tokens: string[]) => void;
  166. /**
  167. * If class exists then remove it, if not, then add it.
  168. */
  169. toggle: (token: string) => void;
  170. /**
  171. * Checks if specified class value exists in class attribute of the element.
  172. */
  173. contains: (className: string) => boolean;
  174. };
  175. /**
  176. * Calling `click()` on an element scrolls it into view if needed, and
  177. * then uses `page.mouse` to click in the center of the element.
  178. * Please see the puppeteer docs for more information.
  179. */
  180. click(options?: ClickOptions): Promise<void>;
  181. /**
  182. * Find a child element that matches the selector, which is the same as
  183. * `element.querySelector(selector)`. Use `>>>` within the
  184. * selector to find an element within a host element's shadow root.
  185. * For example, to select the first `div` inside of the component
  186. * `my-cmp`, which is a child of this element, the call would be
  187. * `element.find('my-cmp >>> div')`. Returns `null` if no
  188. * elements were found.
  189. */
  190. find(selector: FindSelector): Promise<E2EElement>;
  191. /**
  192. * Find all child elements that match the selector, which is the same as
  193. * `element.querySelectorAll(selector)`. Use `>>>` within the
  194. * selector to find elements within a host element's shadow root.
  195. * For example, to select all `li` elements inside of the component
  196. * `my-cmp`, which is a child of this element, the call would be
  197. * `element.findAll('my-cmp >>> li')`. Returns an empty array if
  198. * no elements were found.
  199. */
  200. findAll(selector: FindSelector): Promise<E2EElement[]>;
  201. /**
  202. * Sets focus on the element.
  203. */
  204. focus(): Promise<void>;
  205. /**
  206. * Returns the value of a specified attribute on the element. If the
  207. * given attribute does not exist, the value returned will be null.
  208. */
  209. getAttribute(name: string): string;
  210. /**
  211. * Used to get a property set on a component. For example, if a
  212. * component has the property `elm.myProp`, then calling
  213. * `elm.getProperty('myProp')` would return the `myProp` property value.
  214. */
  215. getProperty(propertyName: string): Promise<any>;
  216. /**
  217. * Returns an object that reports the values of all CSS properties of this
  218. * element after applying active stylesheets and resolving any basic computation
  219. * those values may contain. Individual CSS property values are accessed by
  220. * simply indexing with CSS property names. The method is shortcut and an async
  221. * version of using `window.getComputedStyle(element)` directly.
  222. */
  223. getComputedStyle(pseudoElt?: string | null): Promise<CSSStyleDeclaration>;
  224. /**
  225. * Sets hover on the element.
  226. */
  227. hover(): Promise<void>;
  228. /**
  229. * Gets and sets `id` property of the element.
  230. * Note that `await page.waitForChanges()` must be called before reading
  231. * the value if content has changed.
  232. */
  233. id: string;
  234. /**
  235. * Gets and sets `innerHTML` property of the element.
  236. * Note that `await page.waitForChanges()` must be called before reading
  237. * the value if content has changed.
  238. */
  239. innerHTML: string;
  240. /**
  241. * Gets and sets `innerText` property of the element.
  242. * Note that `await page.waitForChanges()` must be called before reading
  243. * the value if content has changed.
  244. */
  245. innerText: string;
  246. /**
  247. * Resolves to true if the element is visible in the current viewport.
  248. */
  249. isIntersectingViewport(): Promise<boolean>;
  250. /**
  251. * Resolves `true` when the element's style is `display !== 'none'`,
  252. * `visibility !== 'hidden'` and `opacity !== '0'`.
  253. */
  254. isVisible(): Promise<boolean>;
  255. /**
  256. * Node name of the node, which in an element's case is the tag name.
  257. * Note, this will always be upper-cased.
  258. */
  259. nodeName: string;
  260. /**
  261. * The type of a node represented by a number.
  262. * Element = 1, TextNode = 3, Comment = 8,
  263. * Document Fragment (also what a shadow root is) = 11.
  264. */
  265. nodeType: number;
  266. /**
  267. * Gets the element's `outerHTML. This is a read-only property and will
  268. * throw an error if set.
  269. */
  270. outerHTML: string;
  271. /**
  272. * Focuses the element, and then uses `keyboard.down` and `keyboard.up`.
  273. * If key is a single character and no modifier keys besides Shift are
  274. * being held down, a keypress/input event will also be generated. The
  275. * text option can be specified to force an input event to be generated.
  276. * Note: Modifier keys DO effect `elementHandle.press`. Holding down Shift
  277. * will type the text in upper case.
  278. * Key names: https://github.com/puppeteer/puppeteer/blob/main/src/common/USKeyboardLayout.ts
  279. */
  280. press(key: string, options?: {
  281. text?: string;
  282. delay?: number;
  283. }): Promise<void>;
  284. /**
  285. * Removes the attribute on the specified element. Note that
  286. * `await page.waitForChanges()` must be called before reading
  287. * the value if content has changed.
  288. */
  289. removeAttribute(name: string): void;
  290. /**
  291. * Sets the value of an attribute on the specified element. If the
  292. * attribute already exists, the value is updated; otherwise a new
  293. * attribute is added with the specified name and value. The value
  294. * will always be converted to a string. Note that
  295. * `await page.waitForChanges()` must be called before reading
  296. * the value if content has changed.
  297. */
  298. setAttribute(name: string, value: any): void;
  299. /**
  300. * Used to set a property set on a component. For example, if a
  301. * component has the property `elm.myProp`, then calling
  302. * `elm.setProperty('myProp', 88)` would set the value `88` to
  303. * the `myProp` property on the component.
  304. */
  305. setProperty(propertyName: string, value: any): void;
  306. /**
  307. * The ShadowRoot interface of the Shadow DOM API is the root node of a
  308. * DOM subtree that is rendered separately from a document's main DOM tree.
  309. * This value will be `null` if the element does not have a `shadowRoot`.
  310. */
  311. shadowRoot: ShadowRoot;
  312. /**
  313. * Used to test if an event was, or was not dispatched. This method
  314. * returns a promise, that resolves with an EventSpy. The EventSpy
  315. * can be used along with `expect(spy).toHaveReceivedEvent()`,
  316. * `expect(spy).toHaveReceivedEventTimes(x)` and
  317. * `expect(spy).toHaveReceivedEventDetail({...})`.
  318. */
  319. spyOnEvent(eventName: string): Promise<EventSpy>;
  320. /**
  321. * Represents the tab order of the current element. Setting the
  322. * `tabIndex` property will also set the `tabindex` attribute.
  323. */
  324. tabIndex: number;
  325. /**
  326. * Tag name of the element. Note, this will always be upper-cased.
  327. */
  328. tagName: string;
  329. /**
  330. * This method scrolls the element it into view if needed,
  331. * and then uses `page.touchscreen` to tap in the center of the element.
  332. */
  333. tap(): Promise<void>;
  334. /**
  335. * The `textContent` property represents the text content of a node
  336. * and its descendants. Note that `await page.waitForChanges()` must
  337. * be called before reading the value if content has changed.
  338. */
  339. textContent: string;
  340. /**
  341. * Represents the `title` of the element, the text usually displayed in a
  342. * 'tool tip' popup when the mouse is over the displayed node.
  343. */
  344. title: string;
  345. /**
  346. * Toggles a `boolean` attribute (removing it if it is present and adding
  347. * it if it is not present) on the given element. Note that
  348. * `await page.waitForChanges()` must be called before reading
  349. * the value if content has changed. The optional `force` argument is a
  350. * `boolean` value to determine whether the attribute should be added or
  351. * removed, no matter whether the attribute is present or not at the moment.
  352. */
  353. toggleAttribute(name: string, force?: boolean): void;
  354. /**
  355. * This is a convenience method to easily create a `CustomEvent`,
  356. * and dispatch it from the element, to include any custom event
  357. * `detail` data as the second argument.
  358. */
  359. triggerEvent(eventName: string, eventInitDict?: EventInitDict): void;
  360. /**
  361. * Sends a keydown, keypress/input, and keyup event for each character in the text.
  362. * To press a special key, like Control or ArrowDown, use `keyboard.press`.
  363. */
  364. type(text: string, options?: {
  365. delay: number;
  366. }): Promise<void>;
  367. /**
  368. * Waits until the element's style is `display !== 'none'`,
  369. * `visibility !== 'hidden'`, `opacity !== '0'` and the element
  370. * is connected to the document.
  371. */
  372. waitForVisible(): Promise<void>;
  373. /**
  374. * Waits until the element's style is `display === 'none'`, or
  375. * `visibility === 'hidden'`, or `opacity === '0'`, or the element
  376. * is no longer connected to the document.
  377. */
  378. waitForNotVisible(): Promise<void>;
  379. /**
  380. * Waits until the given event is listened in the element.
  381. */
  382. waitForEvent(eventName: string): Promise<any>;
  383. }
  384. export interface E2EElementInternal extends E2EElement {
  385. e2eDispose(): Promise<void>;
  386. e2eRunActions(): Promise<unknown>;
  387. e2eSync(): Promise<void>;
  388. }
  389. export type FindSelector = string | FindSelectorOptions;
  390. export interface FindSelectorOptions {
  391. /**
  392. * Finds an element with text content matching this
  393. * exact value after the whitespace has been trimmed.
  394. */
  395. text?: string;
  396. /**
  397. * Finds an element with text content containing this value.
  398. */
  399. contains?: string;
  400. }
  401. export interface WaitForEventOptions {
  402. timeout?: number;
  403. }
  404. export interface WaitForEvent {
  405. eventName: string;
  406. callback: (ev: any) => void;
  407. }
  408. export interface BrowserWindow extends Window {
  409. stencilOnEvent(id: number, event: any): void;
  410. stencilSerializeEvent(ev: CustomEvent): any;
  411. stencilSerializeEventTarget(target: any): any;
  412. stencilAppLoaded: boolean;
  413. }
  414. export {};