From 561579d9b7b860c5cb3f8131e0dced0c8114463f Mon Sep 17 00:00:00 2001 From: pngwn Date: Mon, 4 Mar 2024 14:03:46 +0000 Subject: [PATCH] fix-tests (#7345) * fix-tests * [tmp] Comment-out * Fix the URL constructor calls in `resolve_wasm_src()`, `should_proxy_wasm_src()`, and `` to handle relative URLs * Remove a circular dependency between lite/index.ts and lite/custom-element/index.ts to solve a bug that the dev app is mounted twice sometimes * Fix js/app/test/image_component_events.spec.ts * Set the `testIgnore` in `.config/playwright.config.js` * Fix the Lite dev mode only to create an app and expose the controller for Playwright, without editors etc. * add changeset * Set the mocked ruff version as 0.2.2 * Extend timeout * Fix to use the built lite files instead of the dev server * add changeset * comment out failed tests * Revert "comment out failed tests" This reverts commit 3580d7988714f49a21e221fe230b26ee86b66a68. * Fix the Gellery component to work in Wasm * Fix js/app/test/file_explorer_component_events.spec.ts to run on Wasm * Ignore queue_full_e2e_test.spec.ts * Revert "[tmp] Comment-out" This reverts commit c775c0cc298ac7e1f49545042e1dc7b6615d179d. * Revert "Extend timeout" This reverts commit 742d1e1e83fc99bd0ac6107a589b75905b7ed593. * Remove a commented out line * Refactor file_explorer_component_events.spec.ts * Revert "fix-tests", restoring the original test-functional.yml content This reverts commit 9ff2a7ddc5b00e1f41b4d7e9c4a64223934cf268. * Set CI step names * [tmp] Revert "Revert "fix-tests", restoring the original test-functional.yml content" This reverts commit de2dbe33173de39304294e6b46151ef1e07f6806. * Revert "[tmp] Revert "Revert "fix-tests", restoring the original test-functional.yml content"" This reverts commit 32154f3bb18d83bad5bce14e254d635dfbe847af. * [tmp] Revert "Revert "[tmp] Revert "Revert "fix-tests", restoring the original test-functional.yml content""" This reverts commit 204075e190eb755a99d2bb449fc339b1f1b5c29b. * Fix vite.config.js removing unnecessary code * Revert "Set the `testIgnore` in `.config/playwright.config.js`" This reverts commit 98dccc5be94ea9c77e69a58f50db577922fe2d67. * Add gallery_component_events.spec.ts * Revert js/app/test * tweak * tweak * revert workflow changes * add changeset --------- Co-authored-by: Yuichiro Tachibana (Tsuchiya) Co-authored-by: gradio-pr-bot --- .changeset/tired-pants-relax.md | 9 ++++ .config/playwright.config.js | 9 ++-- .github/actions/install-all-deps/action.yml | 4 ++ .../actions/install-frontend-deps/action.yml | 12 ++++- .github/workflows/test-functional.yml | 5 +- gradio/components/gallery.py | 12 +++-- js/app/src/lite/custom-element/index.ts | 8 ++- js/app/src/lite/dev/App.svelte | 4 -- js/app/src/lite/index.ts | 2 +- js/app/vite.config.ts | 4 +- js/lite/for_e2e.html | 50 +++++++++++++++++++ js/tootils/src/index.ts | 2 +- js/wasm/src/webworker/index.ts | 2 +- js/wasm/svelte/DownloadLink.svelte | 2 +- js/wasm/svelte/file-url.ts | 4 +- 15 files changed, 105 insertions(+), 24 deletions(-) create mode 100644 .changeset/tired-pants-relax.md create mode 100644 js/lite/for_e2e.html diff --git a/.changeset/tired-pants-relax.md b/.changeset/tired-pants-relax.md new file mode 100644 index 0000000000000..ab31fb44ba090 --- /dev/null +++ b/.changeset/tired-pants-relax.md @@ -0,0 +1,9 @@ +--- +"@gradio/app": patch +"@gradio/lite": patch +"@gradio/tootils": patch +"@gradio/wasm": patch +"gradio": patch +--- + +feat:fix-tests diff --git a/.config/playwright.config.js b/.config/playwright.config.js index 81f48aa67f623..b1ad3d656ce3e 100644 --- a/.config/playwright.config.js +++ b/.config/playwright.config.js @@ -25,21 +25,24 @@ const base = defineConfig({ const normal = defineConfig(base, { globalSetup: "./playwright-setup.js" }); + normal.projects = undefined; // Explicitly unset this field due to https://github.com/microsoft/playwright/issues/28795 const lite = defineConfig(base, { webServer: { - command: "pnpm --filter @gradio/app dev:lite", - url: "http://localhost:9876/lite.html", + command: "python -m http.server 8000 --directory ../js/lite", + url: "http://localhost:8000/", reuseExistingServer: !process.env.CI }, testMatch: [ "**/file_component_events.spec.ts", "**/chatbot_multimodal.spec.ts", - "**/kitchen_sink.spec.ts" + "**/kitchen_sink.spec.ts", + "**/gallery_component_events.spec.ts" ], workers: 1 }); + lite.projects = undefined; // Explicitly unset this field due to https://github.com/microsoft/playwright/issues/28795 export default !!process.env.GRADIO_E2E_TEST_LITE ? lite : normal; diff --git a/.github/actions/install-all-deps/action.yml b/.github/actions/install-all-deps/action.yml index 4f1aeb8b24676..372d4fc0ade77 100644 --- a/.github/actions/install-all-deps/action.yml +++ b/.github/actions/install-all-deps/action.yml @@ -14,6 +14,9 @@ inputs: skip_build: description: 'Skip build' default: 'false' + build-lite: + description: 'Build lite' + default: 'false' test: description: 'Test' default: 'false' @@ -91,6 +94,7 @@ runs: node_auth_token: ${{ inputs.node_auth_token }} npm_token: ${{ inputs.npm_token }} skip_build: ${{ inputs.skip_build }} + build-lite: ${{ inputs.build-lite }} - name: generate json shell: bash if: inputs.os == 'ubuntu-latest' diff --git a/.github/actions/install-frontend-deps/action.yml b/.github/actions/install-frontend-deps/action.yml index 9d2a466cb23fa..7ad9420fb678a 100644 --- a/.github/actions/install-frontend-deps/action.yml +++ b/.github/actions/install-frontend-deps/action.yml @@ -14,6 +14,9 @@ inputs: skip_build: description: 'Skip build' default: 'false' + build-lite: + description: 'Build lite' + default: 'false' os: description: 'OS' default: 'ubuntu-latest' @@ -47,4 +50,11 @@ runs: - name: Build frontend if: inputs.skip_build == 'false' && steps.frontend-cache.outputs.cache-hit != 'true' shell: bash - run: pnpm build \ No newline at end of file + run: pnpm build + - name: Build frontend lite + if: inputs.build-lite == 'true' + shell: bash + run: | + . venv/bin/activate + python -m pip install build + pnpm --filter @gradio/app build:lite \ No newline at end of file diff --git a/.github/workflows/test-functional.yml b/.github/workflows/test-functional.yml index 10b9513f6a09c..633c994a29ac4 100644 --- a/.github/workflows/test-functional.yml +++ b/.github/workflows/test-functional.yml @@ -73,7 +73,10 @@ jobs: run: | . venv/bin/activate pnpm run test:ct - # - run: pnpm --filter @gradio/app test:browser:lite + - name: Run Lite E2E tests + run: | + . venv/bin/activate + pnpm --filter @gradio/app test:browser:lite - name: do check if: always() uses: "gradio-app/github/actions/commit-status@main" diff --git a/gradio/components/gallery.py b/gradio/components/gallery.py index 7a5b8952505ef..691ed4ccd8498 100644 --- a/gradio/components/gallery.py +++ b/gradio/components/gallery.py @@ -12,7 +12,7 @@ from gradio_client.documentation import document from gradio_client.utils import is_http_url_like -from gradio import processing_utils, utils +from gradio import processing_utils, utils, wasm_utils from gradio.components.base import Component from gradio.data_classes import FileData, GradioModel, GradioRootModel from gradio.events import Events @@ -201,9 +201,13 @@ def _save(img): caption=caption, ) - with ThreadPoolExecutor() as executor: - for o in executor.map(_save, value): - output.append(o) + if wasm_utils.IS_WASM: + for img in value: + output.append(_save(img)) + else: + with ThreadPoolExecutor() as executor: + for o in executor.map(_save, value): + output.append(o) return GalleryData(root=output) @staticmethod diff --git a/js/app/src/lite/custom-element/index.ts b/js/app/src/lite/custom-element/index.ts index aa686f4eb769b..3a548cecdc531 100644 --- a/js/app/src/lite/custom-element/index.ts +++ b/js/app/src/lite/custom-element/index.ts @@ -1,4 +1,6 @@ -import { create, type Options } from ".."; +// NOTE: We should only import the types from ".." to avoid the circular dependency of implementations, +// which causes repeated executions of the ".." module in †he dev mode and can lead to multiple instances of the dev app. +import type { create as createLiteAppFunc, Options } from ".."; interface GradioComponentOptions { info: Options["info"]; @@ -28,7 +30,9 @@ function parseRequirementsTxt(content: string): string[] { .filter((r) => r !== ""); } -export function bootstrap_custom_element(): void { +export function bootstrap_custom_element( + create: typeof createLiteAppFunc +): void { const CUSTOM_ELEMENT_NAME = "gradio-lite"; if (customElements.get(CUSTOM_ELEMENT_NAME)) { diff --git a/js/app/src/lite/dev/App.svelte b/js/app/src/lite/dev/App.svelte index 5b46c90083b06..76b1e6347b951 100644 --- a/js/app/src/lite/dev/App.svelte +++ b/js/app/src/lite/dev/App.svelte @@ -79,12 +79,8 @@ def hi(name): controlPageTitle: false, appMode: true }); - // @ts-ignore - window.controller = controller; // For Playwright }); onDestroy(() => { - // @ts-ignore - window.controller = undefined; controller.unmount(); }); diff --git a/js/app/src/lite/index.ts b/js/app/src/lite/index.ts index 02c822db91a4a..0e046e8dcddeb 100644 --- a/js/app/src/lite/index.ts +++ b/js/app/src/lite/index.ts @@ -258,7 +258,7 @@ export function create(options: Options): GradioAppController { // @ts-ignore globalThis.createGradioApp = create; -bootstrap_custom_element(); +bootstrap_custom_element(create); declare let BUILD_MODE: string; if (BUILD_MODE === "dev") { diff --git a/js/app/vite.config.ts b/js/app/vite.config.ts index 3564c751cc0fa..939affd2b864a 100644 --- a/js/app/vite.config.ts +++ b/js/app/vite.config.ts @@ -50,14 +50,12 @@ export default defineConfig(({ mode }) => { const development = mode === "development" || mode === "development:lite"; const is_lite = mode.endsWith(":lite"); - const is_e2e_test = process.env.GRADIO_E2E_TEST_LITE; - return { base: "./", server: { port: 9876, - open: is_e2e_test ? false : is_lite ? "/lite.html" : "/" + open: is_lite ? "/lite.html" : "/" }, build: { diff --git a/js/lite/for_e2e.html b/js/lite/for_e2e.html new file mode 100644 index 0000000000000..fdd342921b281 --- /dev/null +++ b/js/lite/for_e2e.html @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + +
+ + + + diff --git a/js/tootils/src/index.ts b/js/tootils/src/index.ts index 3493576a0ba27..56b8bfe4736ee 100644 --- a/js/tootils/src/index.ts +++ b/js/tootils/src/index.ts @@ -37,7 +37,7 @@ const test_normal = base.extend<{ setup: void }>({ ] }); -const lite_url = "http://localhost:9876/lite.html"; +const lite_url = "http://localhost:8000/for_e2e.html"; // LIte taks a long time to initialize, so we share the page across tests, sacrificing the test isolation. let shared_page_for_lite: Page; const test_lite = base.extend<{ setup: void }>({ diff --git a/js/wasm/src/webworker/index.ts b/js/wasm/src/webworker/index.ts index 66fd93bbb667e..1799e78a0e1b1 100644 --- a/js/wasm/src/webworker/index.ts +++ b/js/wasm/src/webworker/index.ts @@ -80,7 +80,7 @@ async function initializeEnvironment( await micropip.install(["markdown-it-py[linkify]~=2.2.0"]); // On 3rd June 2023, markdown-it-py 3.0.0 has been released. The `gradio` package depends on its `>=2.0.0` version so its 3.x will be resolved. However, it conflicts with `mdit-py-plugins`'s dependency `markdown-it-py >=1.0.0,<3.0.0` and micropip currently can't resolve it. So we explicitly install the compatible version of the library here. await micropip.install(["anyio==3.*"]); // `fastapi` depends on `anyio>=3.4.0,<5` so its 4.* can be installed, but it conflicts with the anyio version `httpx` depends on, `==3.*`. Seems like micropip can't resolve it for now, so we explicitly install the compatible version of the library here. await micropip.add_mock_package("pydantic", "2.4.2"); // PydanticV2 is not supported on Pyodide yet. Mock it here for installing the `gradio` package to pass the version check. Then, install PydanticV1 below. - await micropip.add_mock_package("ruff", "0.1.7"); // `ruff` was added to the requirements of `gradio` for the custom components (https://github.com/gradio-app/gradio/pull/7030), but it's not working on PYodide yet. Also Lite doesn't need it, so mock it here for installing the `gradio` package to pass the version check. + await micropip.add_mock_package("ruff", "0.2.2"); // `ruff` was added to the requirements of `gradio` for the custom components (https://github.com/gradio-app/gradio/pull/7030), but it's not working on PYodide yet. Also Lite doesn't need it, so mock it here for installing the `gradio` package to pass the version check. await micropip.install.callKwargs(gradioWheelUrls, { keep_going: true }); diff --git a/js/wasm/svelte/DownloadLink.svelte b/js/wasm/svelte/DownloadLink.svelte index f0b016211ed0e..609f66f1ab487 100644 --- a/js/wasm/svelte/DownloadLink.svelte +++ b/js/wasm/svelte/DownloadLink.svelte @@ -33,7 +33,7 @@ throw new Error("Wasm worker proxy is not available."); } - const url = new URL(href); + const url = new URL(href, window.location.href); const path = url.pathname; is_downloading = true; diff --git a/js/wasm/svelte/file-url.ts b/js/wasm/svelte/file-url.ts index 5e874dd4ebbaa..493e96e280ac6 100644 --- a/js/wasm/svelte/file-url.ts +++ b/js/wasm/svelte/file-url.ts @@ -9,7 +9,7 @@ export function should_proxy_wasm_src(src: MediaSrc): boolean { return false; } - const url = new URL(src); + const url = new URL(src, window.location.href); if (!is_self_host(url)) { // `src` is not accessing a local server resource, so we don't need to proxy this request to the Wasm worker. return false; @@ -33,7 +33,7 @@ export async function resolve_wasm_src(src: MediaSrc): Promise { return src; } - const url = new URL(src); + const url = new URL(src, window.location.href); const path = url.pathname; return maybeWorkerProxy .httpRequest({