Skip to content

Commit

Permalink
ensure css loads before mounting app (#3573)
Browse files Browse the repository at this point in the history
* ensure css loads before mounting app

* changelog

* fix tests

* change?

* changelog
  • Loading branch information
pngwn authored Mar 27, 2023
1 parent cecd5a2 commit 0d9a08b
Show file tree
Hide file tree
Showing 14 changed files with 73 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Use Gradio API server to send telemetry using `huggingface_hub` [@dawoodkhan82](https://github.com/dawoodkhan82) in [PR 3488](https://github.com/gradio-app/gradio/pull/3488)
- Fixes an an issue where if the Blocks scope was not exited, then State could be shared across sessions, by [@abidlabs](https://github.com/abidlabs) in [PR 3600](https://github.com/gradio-app/gradio/pull/3600)
- Fixed bug where "or" was not being localized in file upload text by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 3599](https://github.com/gradio-app/gradio/pull/3599)
- Ensure CSS has fully loaded before rendering the application, by [@pngwn](https://github.com/pngwn) in [PR 3573](https://github.com/gradio-app/gradio/pull/3573)

## Documentation Changes:

Expand Down
2 changes: 1 addition & 1 deletion demo/code/run.ipynb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: code"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/code/file.css"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "from time import sleep\n", "\n", "\n", "css_file = os.path.join(os.path.abspath(''), \"file.css\")\n", "\n", "\n", "def set_lang(language):\n", " print(language)\n", " return gr.Code.update(language=language)\n", "\n", "\n", "def set_lang_from_path():\n", " sleep(1)\n", " return gr.Code.update((css_file, ), language=\"css\")\n", "\n", "\n", "def code(language, code):\n", " return gr.Code.update(code, language=language)\n", "\n", "\n", "io = gr.Interface(lambda x: x, \"code\", \"code\")\n", "\n", "with gr.Blocks() as demo:\n", " lang = gr.Dropdown(value=\"python\", choices=gr.Code.languages)\n", " with gr.Row():\n", " code_in = gr.Code(language=\"python\", label=\"Input\")\n", " code_out = gr.Code(label=\"Ouput\")\n", " btn = gr.Button(\"Run\")\n", " btn_two = gr.Button(\"Load File\")\n", "\n", " lang.change(set_lang, inputs=lang, outputs=code_in)\n", " btn.click(code, inputs=[lang, code_in], outputs=code_out)\n", " btn_two.click(set_lang_from_path, inputs=None, outputs=code_out)\n", " io.render()\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: code"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "!wget -q https://github.com/gradio-app/gradio/raw/main/demo/code/file.css"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "from time import sleep\n", "\n", "\n", "css_file = os.path.join(os.path.abspath(''), \"file.css\")\n", "\n", "\n", "def set_lang(language):\n", " print(language)\n", " return gr.Code.update(language=language)\n", "\n", "\n", "def set_lang_from_path():\n", " sleep(1)\n", " return gr.Code.update((css_file,), language=\"css\")\n", "\n", "\n", "def code(language, code):\n", " return gr.Code.update(code, language=language)\n", "\n", "\n", "io = gr.Interface(lambda x: x, \"code\", \"code\")\n", "\n", "with gr.Blocks() as demo:\n", " lang = gr.Dropdown(value=\"python\", choices=gr.Code.languages)\n", " with gr.Row():\n", " code_in = gr.Code(\n", " language=\"python\",\n", " label=\"Input\",\n", " value='def all_odd_elements(sequence):\\n \"\"\"Returns every odd element of the sequence.\"\"\"',\n", " )\n", " code_out = gr.Code(label=\"Ouput\")\n", " btn = gr.Button(\"Run\")\n", " btn_two = gr.Button(\"Load File\")\n", "\n", " lang.change(set_lang, inputs=lang, outputs=code_in)\n", " btn.click(code, inputs=[lang, code_in], outputs=code_out)\n", " btn_two.click(set_lang_from_path, inputs=None, outputs=code_out)\n", " io.render()\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
8 changes: 6 additions & 2 deletions demo/code/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def set_lang(language):

def set_lang_from_path():
sleep(1)
return gr.Code.update((css_file, ), language="css")
return gr.Code.update((css_file,), language="css")


def code(language, code):
Expand All @@ -25,7 +25,11 @@ def code(language, code):
with gr.Blocks() as demo:
lang = gr.Dropdown(value="python", choices=gr.Code.languages)
with gr.Row():
code_in = gr.Code(language="python", label="Input")
code_in = gr.Code(
language="python",
label="Input",
value='def all_odd_elements(sequence):\n """Returns every odd element of the sequence."""',
)
code_out = gr.Code(label="Ouput")
btn = gr.Button("Run")
btn_two = gr.Button("Load File")
Expand Down
2 changes: 1 addition & 1 deletion style.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,4 @@ Nothing

## Variable

Nothing
Nothing
32 changes: 20 additions & 12 deletions ui/packages/app/src/Index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,28 @@
let config: Config;
let loading_text: string = "Loading...";
function mount_custom_css(target: HTMLElement, css_string: string | null) {
async function mount_custom_css(
target: HTMLElement,
css_string: string | null
) {
if (css_string) {
let style = document.createElement("style");
style.innerHTML = css_string;
target.appendChild(style);
}
mount_css(config.root + "/theme.css", document.head);
await mount_css(config.root + "/theme.css", document.head);
if (!config.stylesheets) return;
for (let stylesheet of config.stylesheets) {
let absolute_link =
stylesheet.startsWith("http:") || stylesheet.startsWith("https:");
mount_css(
absolute_link ? stylesheet : config.root + "/" + stylesheet,
document.head
);
}
await Promise.all(
config.stylesheets.map((stylesheet) => {
let absolute_link =
stylesheet.startsWith("http:") || stylesheet.startsWith("https:");
return mount_css(
absolute_link ? stylesheet : config.root + "/" + stylesheet,
document.head
);
})
);
}
async function reload_check(root: string) {
Expand Down Expand Up @@ -178,6 +184,7 @@
};
let app: Awaited<ReturnType<typeof client>>;
let css_ready = false;
function handle_status(_status: SpaceStatus) {
status = _status;
}
Expand All @@ -201,7 +208,8 @@
detail: "RUNNING"
};
mount_custom_css(wrapper, config.css);
await mount_custom_css(wrapper, config.css);
css_ready = true;
window.__is_colab__ = config.is_colab;
if (config.dev_mode) {
Expand Down Expand Up @@ -314,7 +322,7 @@
is_space={config.is_space}
{app_mode}
/>
{:else if config && Blocks}
{:else if config && Blocks && css_ready}
<Blocks
{app}
{...config}
Expand Down
4 changes: 3 additions & 1 deletion ui/packages/app/test/blocks_inputs.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test, expect, Page } from "@playwright/test";
import { mock_theme, wait_for_page } from "./utils";

function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
Expand Down Expand Up @@ -28,7 +29,8 @@ function mock_api(page: Page, body: Array<unknown>) {
test("renders the correct elements", async ({ page }) => {
await mock_demo(page, "blocks_inputs");
await mock_api(page, [["hi dawood"]]);
await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

const textboxes = await page.getByLabel("Input");

Expand Down
4 changes: 3 additions & 1 deletion ui/packages/app/test/blocks_kinematics.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test, expect, Page } from "@playwright/test";
import { mock_theme, wait_for_page } from "./utils";

function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
Expand Down Expand Up @@ -28,7 +29,8 @@ function mock_api(page: Page, body: Array<unknown>) {
test("renders the correct elements", async ({ page }) => {
await mock_demo(page, "blocks_kinematics");
await mock_api(page, [[25, 45]]);
await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

await Promise.all([
page.click("button:has-text('Run')"),
Expand Down
4 changes: 3 additions & 1 deletion ui/packages/app/test/blocks_page_load.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test, expect, Page } from "@playwright/test";
import { mock_theme, wait_for_page } from "./utils";

function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
Expand Down Expand Up @@ -28,7 +29,8 @@ function mock_api(page: Page, body: Array<unknown>) {
test("renders the correct elements", async ({ page }) => {
await mock_demo(page, "blocks_page_load");
await mock_api(page, [["Welcome! This page has loaded for Frank"]]);
await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

const textbox = await page.getByLabel("Name");

Expand Down
7 changes: 5 additions & 2 deletions ui/packages/app/test/blocks_xray.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test, expect, Page } from "@playwright/test";
import { mock_theme, wait_for_page } from "./utils";

function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
Expand Down Expand Up @@ -27,7 +28,8 @@ function mock_api(page: Page, body: Array<unknown>) {

test("renders the correct elements", async ({ page }) => {
await mock_demo(page, "blocks_xray");
await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

const description = await page.getByTestId("markdown");
await expect(description).toContainText("Detect Disease From Scan");
Expand Down Expand Up @@ -56,7 +58,8 @@ test("can run an api request and display the data", async ({ page }) => {
]
]);

await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

await page.getByLabel("Covid").check();
await page.getByLabel("Lung Cancer").check();
Expand Down
4 changes: 3 additions & 1 deletion ui/packages/app/test/input_output.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test, expect, Page } from "@playwright/test";
import { mock_theme, wait_for_page } from "./utils";

function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
Expand Down Expand Up @@ -28,7 +29,8 @@ function mock_api(page: Page, body: Array<unknown>) {
test("a component acts as both input and output", async ({ page }) => {
await mock_demo(page, "input_output");
await mock_api(page, [["tset"]]);
await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

const textbox = await page.getByLabel("Input-Output");

Expand Down
7 changes: 5 additions & 2 deletions ui/packages/app/test/kitchen_sink.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { test, expect, Page } from "@playwright/test";
import { BASE64_IMAGE, BASE64_AUDIO } from "./media_data";
import { mock_theme, wait_for_page } from "./utils";

function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
Expand Down Expand Up @@ -28,7 +29,8 @@ function mock_api(page: Page, body: Array<unknown>) {

test("test inputs", async ({ page }) => {
await mock_demo(page, "kitchen_sink");
await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

const textbox = await page.getByLabel("Textbox").nth(0);
await expect(textbox).toHaveValue("Lorem ipsum");
Expand Down Expand Up @@ -209,7 +211,8 @@ test("test outputs", async ({ page }) => {
]
]);

await page.goto("http://localhost:9876");
await mock_theme(page);
await wait_for_page(page);

const submit_button = await page.locator("button", { hasText: /Submit/ });

Expand Down
14 changes: 2 additions & 12 deletions ui/packages/app/test/outbreak_forecast.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { test, expect, Page } from "@playwright/test";
import { BASE64_PLOT_IMG } from "./media_data";
import { mock_theme, wait_for_page } from "./utils";

function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
Expand All @@ -12,17 +13,6 @@ function mock_demo(page: Page, demo: string) {
});
}

function mock_theme(page: Page) {
return page.route("**/theme.css", (route) => {
return route.fulfill({
headers: {
"Access-Control-Allow-Origin": "*"
},
path: `./test/mocks/theme.css`
});
});
}

function mock_api(page: Page, body: Array<unknown>) {
return page.route("**/run/predict", (route) => {
const id = JSON.parse(route.request().postData()!).fn_index;
Expand All @@ -41,7 +31,7 @@ test("matplotlib", async ({ page }) => {
await mock_demo(page, "outbreak_forecast");
await mock_api(page, [[{ type: "matplotlib", plot: BASE64_PLOT_IMG }]]);
await mock_theme(page);
await page.goto("http://localhost:9876");
await wait_for_page(page);

await page.getByLabel("Plot Type").click();
await page.getByRole("button", { name: "Matplotlib" }).click();
Expand Down
5 changes: 3 additions & 2 deletions ui/packages/app/test/slider_release.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test, expect, Page, Locator } from "@playwright/test";
import { mock_theme, wait_for_page } from "./utils";

//taken from: https://github.com/microsoft/playwright/issues/20032
async function changeSlider(
Expand Down Expand Up @@ -59,8 +60,8 @@ function mock_api(page: Page) {
test("slider release", async ({ page }) => {
await mock_demo(page, "slider_release");
await mock_api(page);
await page.goto("http://localhost:9876");

await mock_theme(page);
await wait_for_page(page);
const slider = page.getByLabel("Slider");

await changeSlider(page, slider, slider, 0.7);
Expand Down
17 changes: 17 additions & 0 deletions ui/packages/app/test/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Page } from "@playwright/test";

export function mock_theme(page: Page) {
return page.route("**/theme.css", (route) => {
return route.fulfill({
headers: {
"Access-Control-Allow-Origin": "*"
},
path: `./test/mocks/theme.css`
});
});
}

export async function wait_for_page(page: Page) {
await page.goto("http://localhost:9876");
await page.waitForResponse("**/theme.css");
}

0 comments on commit 0d9a08b

Please sign in to comment.