From ba67a1740072844102f57f9849c09268955f766d Mon Sep 17 00:00:00 2001 From: Robin Lindhout Date: Thu, 19 Jan 2023 11:18:02 +0100 Subject: [PATCH] feat: migrate to puppeteer-web --- package.json | 1 + src/detox.native.tsx | 2 - src/detox.tsx | 470 ------------------------------------------- src/helpers.ts | 3 +- src/index.ts | 2 - yarn.lock | 180 ++++++++++++++++- 6 files changed, 180 insertions(+), 478 deletions(-) delete mode 100644 src/detox.native.tsx delete mode 100644 src/detox.tsx diff --git a/package.json b/package.json index f925211..518a0f9 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "registry": "https://registry.npmjs.org/" }, "devDependencies": { + "detox-puppeteer": "^5.0.0", "@commitlint/config-conventional": "^11.0.0", "@react-native-community/eslint-config": "^2.0.0", "@release-it/conventional-changelog": "^2.0.0", diff --git a/src/detox.native.tsx b/src/detox.native.tsx deleted file mode 100644 index 1313e33..0000000 --- a/src/detox.native.tsx +++ /dev/null @@ -1,2 +0,0 @@ -import { by, device, element, expect } from 'detox'; -export { by, device, element, expect }; diff --git a/src/detox.tsx b/src/detox.tsx deleted file mode 100644 index bcee3f9..0000000 --- a/src/detox.tsx +++ /dev/null @@ -1,470 +0,0 @@ -import type { ElementHandle, Page } from 'puppeteer'; -import 'expect-puppeteer'; - -interface WebMatcher { - get(): { selector: string; xpath: string | undefined }; - and(by: WebMatcher): WebMatcher; - withAncestor(parentBy: WebMatcher): WebMatcher; - withDescendant(childBy: WebMatcher): WebMatcher; -} - -let WebMatcherBuilder = function ( - startSelector: string, - startXpath?: string -): WebMatcher { - let selector = startSelector; - let xpath = startXpath; - return { - and: function (by) { - if (xpath) { - console.error('and is not supported with by.text() on web'); - } - selector = `${by}${selector}`; - return this; - }, - withAncestor: function (parentBy) { - if (xpath) { - console.error('and is not supported with by.text() on web'); - } - selector = `${parentBy} ${selector}`; - return this; - }, - withDescendant: function (childBy) { - if (xpath) { - console.error('and is not supported with by.text() on web'); - } - selector = `${selector} ${childBy}`; - return this; - }, - get: () => ({ - xpath, - selector, - }), - }; -}; - -interface WebBy { - id(id: string): WebMatcher; - text(text: string): WebMatcher; - - label(label: string): WebMatcher; - type(nativeViewType: string): WebMatcher; - traits(traits: string[]): WebMatcher; -} - -const by: WebBy = { - id: (id: string) => WebMatcherBuilder(`[data-testid='${id}']`), - text: (text: string) => WebMatcherBuilder('', `//*[text() = "${text}"]`), - label: (label: string) => WebMatcherBuilder(`[aria-label="${label}"]`), - type: (type: string) => { - notImplemented(`type(${type})`); - return WebMatcherBuilder(''); - }, - traits: (traits: string[]) => { - // TODO: improve - return WebMatcherBuilder(`[aria-role="${traits[0]}"]`); - }, -}; - -let appLaunchArgs: Detox.DeviceLaunchAppConfig | undefined; - -type WebDevice = Omit< - Detox.Device, - 'getPlatform' | 'reverseTcpPort' | 'unreverseTcpPort' -> & { - getPlatform: () => 'android' | 'ios' | 'web'; -}; - -function notImplemented(funcName: string) { - console.log( - `${funcName} not supported on the web platform only on native devices` - ); -} - -const device: WebDevice = { - id: 'puppeteer', - name: 'puppeteer', - appLaunchArgs: { - get: () => appLaunchArgs || {}, - reset: () => (appLaunchArgs = {}), - modify: (args: object) => { - appLaunchArgs = { ...appLaunchArgs, ...args }; - }, - }, - launchApp: async (arg) => { - appLaunchArgs = arg; - if (arg?.delete) { - await page.evaluateOnNewDocument(() => { - localStorage.clear(); - }); - } - await page.goto('http://localhost:3000'); - }, - selectApp: async (name: string) => { - notImplemented(`selectApp(${name})`); - }, - terminateApp: async (bundle?: string) => { - notImplemented(`terminateApp(${bundle || ''})`); - }, - sendToHome: async () => { - await page.goto('http://localhost:3000'); - }, - reloadReactNative: async () => { - await page.goto('http://localhost:3000'); - await page.reload(); - }, - installApp: async (path?: any) => { - notImplemented(`installApp(${path || ''})`); - }, - uninstallApp: async (bundle?: string) => { - await page.evaluateOnNewDocument(() => { - localStorage.clear(); - }); - notImplemented(`uninstallApp(${bundle || ''})`); - }, - openURL: async (params: { url: string; sourceApp?: string }) => { - notImplemented(`openURL(${JSON.stringify(params)})`); - }, - sendUserNotification: async (..._: any[]) => { - notImplemented('sendUserNotification()'); - }, - sendUserActivity: async (..._: any[]) => { - notImplemented('sendUserActivity()'); - }, - setOrientation: async (orientation: Detox.Orientation) => { - notImplemented(`setOrientation(${orientation})`); - }, - setLocation: async (latitude: number, longitude: number) => { - const client = await page.target().createCDPSession(); - await client.send('Emulation.setGeolocationOverride', { - accuracy: 100, - latitude, - longitude, - }); - }, - - setURLBlacklist: async (lists: string[]) => { - notImplemented(`setURLBlacklist(${lists?.join(', ')})`); - }, - enableSynchronization: async () => { - notImplemented('enableSynchronization()'); - }, - disableSynchronization: async () => { - notImplemented('disableSynchronization()'); - }, - resetContentAndSettings: async () => { - await page.evaluateOnNewDocument(() => { - localStorage.clear(); - }); - }, - getPlatform: () => { - return 'web'; - }, - takeScreenshot: async (name: string) => { - try { - const path = name + '.png'; - await page.screenshot({ - path, - }); - return path; - } catch (e) { - console.log('takeScreenshot error', e); - return ''; - } - }, - shake: async () => { - notImplemented('shake()'); - }, - setBiometricEnrollment: async (_: boolean) => { - notImplemented('setBiometricEnrollment()'); - }, - matchFace: async () => { - notImplemented('matchFace()'); - }, - unmatchFace: async () => { - notImplemented('unmatchFace()'); - }, - matchFinger: async () => { - notImplemented('matchFinger()'); - }, - unmatchFinger: async () => { - notImplemented('unmatchFinger()'); - }, - clearKeychain: async () => { - notImplemented('clearKeychain()'); - }, - pressBack: async () => { - await page.goBack(); - }, - getUiDevice: async () => { - notImplemented('getUiDevice()'); - }, -}; - -interface WebElementActions { - core: ElementHandle; - tap(): Promise; - longPress(): Promise; - longPressAndDrag( - duration: number, - normalizedPositionX: number, - normalizedPositionY: number, - targetElement: ElementHandle, - normalizedTargetPositionX: number, - normalizedTargetPositionY: number, - speed: Detox.Speed, - holdDuration: number - ): Promise; - multiTap(times: number): Promise; - tapAtPoint(point: { x: number; y: number }): Promise; - typeText(text: string): Promise; - replaceText(text: string): Promise; - clearText(): Promise; - tapBackspaceKey(): Promise; - tapReturnKey(): Promise; - scroll( - pixels: number, - direction: Detox.Direction, - startPositionX?: number, - startPositionY?: number - ): Promise; - scrollTo(edge: Detox.Direction): Promise; - swipe( - direction: Detox.Direction, - speed?: Detox.Speed, - percentage?: number, - normalizedStartingPointX?: number, - normalizedStartingPointY?: number - ): Promise; - setColumnToValue(column: number, value: string): Promise; - setDatePickerDate(dateString: string, dateFormat: string): Promise; - pinchWithAngle( - direction: Detox.PinchDirection, - speed: Detox.Speed, - angle: number - ): Promise; - pinch(scale: number, speed: Detox.Speed, angle: number): Promise; -} - -async function findElement(p: WebMatcher): Promise { - const { selector, xpath } = p.get(); - const pa = await page; - - const result = xpath - ? await pa.waitForXPath(xpath, { - timeout: 2000, - })! - : await pa.waitForSelector(selector, { - timeout: 2000, - }); - - return result!; -} -// async function findElementWithRetry(p: WebMatcher): Promise { -// try { -// return await findElement(p); -// } catch (error) { -// await sleep(1000); -// return await findElement(p); -// } -// } - -const element: (p: WebMatcher) => Promise = async ( - p: WebMatcher -): Promise => { - const { selector } = p.get(); - - const e = await findElement(p); - - if (!e) { - throw Error('element not found'); - } - - return { - core: e, - replaceText: async (v: string) => { - await e.click({ clickCount: 3 }); - await e.type(v, { delay: 20 }); - }, - tapReturnKey: async () => { - await page.keyboard.press('Enter'); - }, - tap: async () => { - await e.click({ delay: 10 }); - }, - scroll: async ( - offset: number, - direction: 'up' | 'down', - startPositionX?: number, - startPositionY?: number - ) => { - if (startPositionX || startPositionY) { - notImplemented('scroll() with startPositionX and/or startPositionY'); - } - - await page.evaluate( - (sel: string, dir: Detox.Direction, off: number) => { - const scrollView = document.querySelector(sel); - if (!scrollView) { - throw Error('cannot scroll element'); - } - - switch (dir) { - case 'up': - scrollView.scrollBy(0, -off); - break; - case 'down': - scrollView.scrollBy(0, off); - break; - } - }, - selector, - direction, - offset - ); - }, - clearText: async () => { - await e.click({ clickCount: 3 }); - await e.type(''); - }, - longPress: async () => { - await e.click({ - delay: 600, - }); - }, - longPressAndDrag: async ( - duration: number, - normalizedPositionX: number, - normalizedPositionY: number, - targetElement: ElementHandle, - normalizedTargetPositionX: number, - normalizedTargetPositionY: number, - speed: Detox.Speed, - holdDuration: number - ) => { - notImplemented('longPressAndDrag()'); - await e.click({ - delay: holdDuration, - }); - }, - multiTap: async (times: number) => { - await e.click({ clickCount: times }); - }, - pinch: async (scale: number, speed: Detox.Speed, angle: number) => { - notImplemented(`pinch(${scale},${speed}, ${angle})`); - }, - pinchWithAngle: async ( - direction: Detox.PinchDirection, - speed: Detox.Speed, - angle: number - ) => { - notImplemented(`pinch(${direction},${speed}, ${angle})`); - }, - scrollTo: async (edge: Detox.Direction) => { - await page.evaluate( - (sel: string, edg: Detox.Direction) => { - const scrollView = document.querySelector(sel); - if (!scrollView) { - throw Error('cannot scroll element'); - } - - switch (edg) { - case 'bottom': - scrollView.scrollTop = scrollView.scrollHeight; - break; - case 'left': - scrollView.scrollLeft = 0; - break; - case 'right': - scrollView.scrollLeft = scrollView.scrollWidth; - break; - case 'top': - scrollView.scrollTop = 0; - break; - } - }, - selector, - edge - ); - }, - setColumnToValue: async (column: number, value: string) => { - notImplemented(`setColumnToValue(${column}, ${value})`); - }, - setDatePickerDate: async (dateString: string, dateFormat: string) => { - notImplemented(`setDatePickerDate(${dateString}, ${dateFormat})`); - }, - swipe: async ( - direction: Detox.Direction, - speed?: Detox.Speed, - percentage?: number, - normalizedStartingPointX?: number, - normalizedStartingPointY?: number - ) => { - notImplemented( - `swipe(${direction}, ${speed}, ${percentage}, ${normalizedStartingPointX}, ${normalizedStartingPointY})` - ); - }, - tapAtPoint: async (point: { x: number; y: number }) => { - const rect = await page.evaluate((el) => { - const { x, y } = el.getBoundingClientRect(); - return { x, y }; - }, e); - - const offset = { x: point.x, y: point.y }; - await page.mouse.click(rect.x + offset.x, rect.y + offset.y); - }, - tapBackspaceKey: async () => { - await page.keyboard.press('Backspace'); - }, - typeText: async (text: string) => { - for (let i = 0; i < text.length; i++) { - await page.keyboard.sendCharacter(text.charAt(i)); - } - }, - }; -}; - -function expectImpl(e: WebElementActions) { - return { - toExist: () => { - return !!e.core; - }, - toBeVisible: async () => { - if (!e.core) { - return false; - } - - return isLocatorReady(e.core, page); - }, - }; -} - -async function isLocatorReady(el: ElementHandle, page: Page) { - const isVisibleHandle = await page.evaluateHandle((e) => { - const style = window.getComputedStyle(e); - return ( - style && - style.display !== 'none' && - style.visibility !== 'hidden' && - style.opacity !== '0' - ); - }, el); - let visible = await isVisibleHandle.jsonValue(); - const box = await el.boxModel(); - return !!(visible && box); -} - -function init(_?: any, _1?: any) { - return null; -} - -const webElementAsDetoxType = element as unknown as Detox.ElementFacade; -const webBy = by as unknown as Detox.ByFacade; -const webExpect = expectImpl as unknown as Detox.ExpectFacade; -export { - webBy as by, - device, - webElementAsDetoxType as element, - webExpect as expect, - init, -}; diff --git a/src/helpers.ts b/src/helpers.ts index 60eed9a..cbc3101 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,4 +1,5 @@ -import { by, device, element, expect } from './detox'; +//@ts-ignore +import { by, device, element, expect } from 'detox-puppeteer'; export async function replaceTextById( id: string, diff --git a/src/index.ts b/src/index.ts index d4b455a..ff1dfab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import { by, device, element, expect } from './detox'; import { replaceTextById, isVisibleByText, @@ -10,7 +9,6 @@ import { sleep, } from './helpers'; -export { by, device, element, expect }; export { replaceTextById, isVisibleByText, diff --git a/yarn.lock b/yarn.lock index 4479187..ef11c64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1220,6 +1220,60 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@ffmpeg-installer/darwin-arm64@4.1.5": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz#b7b5c262dd96d1aea4807514e1cdcf6e11f82743" + integrity sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA== + +"@ffmpeg-installer/darwin-x64@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz#48e1706c690e628148482bfb64acb67472089aaa" + integrity sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw== + +"@ffmpeg-installer/ffmpeg@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz#87fdb9e7d180e8d78f7903f9441e36f978938a90" + integrity sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg== + optionalDependencies: + "@ffmpeg-installer/darwin-arm64" "4.1.5" + "@ffmpeg-installer/darwin-x64" "4.1.0" + "@ffmpeg-installer/linux-arm" "4.1.3" + "@ffmpeg-installer/linux-arm64" "4.1.4" + "@ffmpeg-installer/linux-ia32" "4.1.0" + "@ffmpeg-installer/linux-x64" "4.1.0" + "@ffmpeg-installer/win32-ia32" "4.1.0" + "@ffmpeg-installer/win32-x64" "4.1.0" + +"@ffmpeg-installer/linux-arm64@4.1.4": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz#7219f3f901bb67f7926cb060b56b6974a6cad29f" + integrity sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg== + +"@ffmpeg-installer/linux-arm@4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz#c554f105ed5f10475ec25d7bec94926ce18db4c1" + integrity sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg== + +"@ffmpeg-installer/linux-ia32@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz#adad70b0d0d9d8d813983d6e683c5a338a75e442" + integrity sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ== + +"@ffmpeg-installer/linux-x64@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz#b4a5d89c4e12e6d9306dbcdc573df716ec1c4323" + integrity sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A== + +"@ffmpeg-installer/win32-ia32@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz#6eac4fb691b64c02e7a116c1e2d167f3e9b40638" + integrity sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw== + +"@ffmpeg-installer/win32-x64@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz#17e8699b5798d4c60e36e2d6326a8ebe5e95a2c5" + integrity sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg== + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -2457,6 +2511,11 @@ async-retry@1.3.1: dependencies: retry "0.12.0" +async@>=0.2.9: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + async@^2.4.0: version "2.6.3" resolved "https://registry.npmjs.org/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -3596,6 +3655,13 @@ debug@4, debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "2.1.2" +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -3761,6 +3827,16 @@ detect-newline@^3.0.0: resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detox-puppeteer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detox-puppeteer/-/detox-puppeteer-5.0.0.tgz#3e19876521608145a2e2c0e3236e963b3e907bde" + integrity sha512-7hcoObicJjAcegVNZsRoHPI9WuVflREW/3Cjd0r+efi6xTD/duI15p5a2fQ/SgU969XHk6Zmb0EKFe8W34L98Q== + dependencies: + lodash "^4.17.19" + puppeteer "^11.0.0" + puppeteer-screen-recorder "^2.0.2" + tslib "^2.2.0" + detox@^18.18.1: version "18.18.1" resolved "https://registry.npmjs.org/detox/-/detox-18.18.1.tgz#11fdfbcf698ee79f6baaecc7f09bacc37134841b" @@ -3797,6 +3873,11 @@ devtools-protocol@0.0.883894: resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.883894.tgz#d403f2c75cd6d71c916aee8dde9258da988a4da9" integrity sha512-33idhm54QJzf3Q7QofMgCvIVSd2o9H3kQPWaKT/fhoZh+digc+WSiMhbkeG3iN79WY4Hwr9G05NpbhEVrsOYAg== +devtools-protocol@0.0.901419: + version "0.0.901419" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.901419.tgz#79b5459c48fe7e1c5563c02bd72f8fec3e0cebcd" + integrity sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ== + diff-sequences@^26.6.2: version "26.6.2" resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" @@ -4595,6 +4676,14 @@ flatted@^3.1.0: resolved "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== +fluent-ffmpeg@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz#c952de2240f812ebda0aa8006d7776ee2acf7d74" + integrity sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q== + dependencies: + async ">=0.2.9" + which "^1.1.1" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -7030,6 +7119,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -7138,6 +7232,13 @@ node-fetch@2.6.1, node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.1: resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +node-fetch@2.6.5: + version "2.6.5" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" + integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + dependencies: + whatwg-url "^5.0.0" + node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -7852,7 +7953,7 @@ progress@2.0.1: resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== -progress@^2.0.0: +progress@2.0.3, progress@^2.0.0: version "2.0.3" resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -7942,6 +8043,15 @@ pupa@^2.1.1: dependencies: escape-goat "^2.0.0" +puppeteer-screen-recorder@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/puppeteer-screen-recorder/-/puppeteer-screen-recorder-2.1.2.tgz#7f88b175a662803c59f0984d9c1827ff5f364d0b" + integrity sha512-vR7zB8XiJ/UQxZybdmaTBtiuohyvySamP+lEa7Vp+j2f1AGEznZGvrJTJjq7TqemdWzq9YJ0gEOZroPU4pzNZQ== + dependencies: + fluent-ffmpeg "^2.1.2" + optionalDependencies: + "@ffmpeg-installer/ffmpeg" "^1.1.0" + puppeteer@^10.1.0: version "10.1.0" resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-10.1.0.tgz#6ee1d7e30401a967f4403bd42ace9e51e399504f" @@ -7960,6 +8070,24 @@ puppeteer@^10.1.0: unbzip2-stream "1.3.3" ws "7.4.6" +puppeteer@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-11.0.0.tgz#0808719c38e15315ecc1b1c28911f1c9054d201f" + integrity sha512-6rPFqN1ABjn4shgOICGDBITTRV09EjXVqhDERBDKwCLz0UyBxeeBH6Ay0vQUJ84VACmlxwzOIzVEJXThcF3aNg== + dependencies: + debug "4.3.2" + devtools-protocol "0.0.901419" + extract-zip "2.0.1" + https-proxy-agent "5.0.0" + node-fetch "2.6.5" + pkg-dir "4.2.0" + progress "2.0.3" + proxy-from-env "1.1.0" + rimraf "3.0.2" + tar-fs "2.1.1" + unbzip2-stream "1.4.3" + ws "8.2.3" + q@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -9204,7 +9332,17 @@ tar-fs@2.0.0: pump "^3.0.0" tar-stream "^2.0.0" -tar-stream@^2.0.0: +tar-fs@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.0.0, tar-stream@^2.1.4: version "2.2.0" resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== @@ -9391,6 +9529,11 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -9418,6 +9561,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + tsutils@^3.17.1: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -9532,6 +9680,14 @@ unbzip2-stream@1.3.3: buffer "^5.2.1" through "^2.3.8" +unbzip2-stream@1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + unc-path-regex@^0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" @@ -9746,6 +9902,11 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -9773,6 +9934,14 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.7.0" resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" @@ -9803,7 +9972,7 @@ which-pm-runs@^1.0.0: resolved "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= -which@^1.2.9, which@^1.3.1: +which@^1.1.1, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -9888,6 +10057,11 @@ ws@7.4.6: resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + ws@^1.1.0, ws@^1.1.5: version "1.1.5" resolved "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51"