Fix hotpatched assets (#4326)
* wip: fixes to get docsite working again * Fix asset location with PIC in hot patched builds * Add an hidden cli flag to exit early in hot patch tests on failure * add a test for hot patching with assets * fix clippy * fix looks_like_manganis_symbol * longer timeout for hot patching in CI * log page content * log assets * Log asset after write * record a playwright trace * Explicitly enable cargo incremental for hot patching * fix retry for patch test * reset asset * disable hot patching test for new exports * add nightly playwright * use different toolchain names * use beta instead of nightly for less thrashing * add failing test * workaround hot reloading bug * restore swapping asset tests * add toolchain --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
6cc379718b
commit
2071be2b67
20 files changed
+365
-125
No files matched your search
+12
-12
@@ -9,17 +9,17 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.52.0"
|
||||
"@playwright/test": "^1.53.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz",
|
||||
"integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==",
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.1.tgz",
|
||||
"integrity": "sha512-Z4c23LHV0muZ8hfv4jw6HngPJkbbtZxTkxPNIg7cJcTc9C28N/p2q7g3JZS2SiKBBHJ3uM1dgDye66bB7LEk5w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.52.0"
|
||||
"playwright": "1.53.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -44,13 +44,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz",
|
||||
"integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==",
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.1.tgz",
|
||||
"integrity": "sha512-LJ13YLr/ocweuwxyGf1XNFWIU4M2zUSo149Qbp+A4cpwDjsxRPj7k6H25LBrEHiEwxvRbD8HdwvQmRMSvquhYw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.52.0"
|
||||
"playwright-core": "1.53.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -63,9 +63,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz",
|
||||
"integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==",
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.1.tgz",
|
||||
"integrity": "sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.52.0"
|
||||
"@playwright/test": "^1.53.1"
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ module.exports = defineConfig({
|
||||
// baseURL: 'http://127.0.0.1:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
trace: "retain-on-failure",
|
||||
// Increase the timeout for navigations to give dx time to build the project
|
||||
navigationTimeout: 50 * 60 * 1000,
|
||||
},
|
||||
@@ -202,5 +202,13 @@ module.exports = defineConfig({
|
||||
reuseExistingServer: !process.env.CI,
|
||||
stdout: "pipe",
|
||||
},
|
||||
{
|
||||
command:
|
||||
'rm -rf ./web-hot-patch-temp && cp -r ./web-hot-patch ./web-hot-patch-temp && cd web-hot-patch-temp && cargo run --manifest-path ../../cli/Cargo.toml --release -- serve --verbose --force-sequential --platform web --addr "127.0.0.1" --port 9980 --hot-patch --exit-on-error',
|
||||
port: 9980,
|
||||
timeout: 50 * 60 * 1000,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
stdout: "pipe",
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
target
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "dioxus-playwright-web-patch-test"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
description = "Playwright test for Dioxus Web"
|
||||
license = "MIT OR Apache-2.0"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
dioxus = { path = "../../dioxus", features = ["web"]}
|
||||
|
||||
[workspace]
|
||||
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: rgb(100, 100, 100);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#main {
|
||||
background-color: red;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,30 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
const CSS: Asset = asset!("/assets/style.css");
|
||||
const IMAGE: Asset = asset!("/assets/toasts.png");
|
||||
|
||||
fn app() -> Element {
|
||||
let mut num = use_signal(|| 0);
|
||||
|
||||
rsx! {
|
||||
document::Link {
|
||||
href: CSS,
|
||||
rel: "stylesheet",
|
||||
}
|
||||
img {
|
||||
id: "toasts",
|
||||
src: IMAGE,
|
||||
}
|
||||
button {
|
||||
id: "increment-button",
|
||||
onclick: move |_| {
|
||||
num += 1;
|
||||
},
|
||||
"Click me! Count: {num}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dioxus::launch(app);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// @ts-check
|
||||
const { test, expect } = require("@playwright/test");
|
||||
|
||||
const hotPatchTimeout = {
|
||||
timeout: 1000 * 60 * 2, // 2 minute
|
||||
};
|
||||
|
||||
test("button click", async ({ page }) => {
|
||||
const fs = require("fs");
|
||||
const mainPath = "web-hot-patch-temp/src/main.rs";
|
||||
var mainContent = fs.readFileSync(mainPath, "utf8");
|
||||
const stylePath = "web-hot-patch-temp/assets/style.css";
|
||||
var styleContent = fs.readFileSync(stylePath, "utf8");
|
||||
|
||||
// Reset any changes made to the main.rs and style.css files.
|
||||
mainContent = mainContent.replace(/num \+= 2;/g, "num += 1;");
|
||||
mainContent = mainContent.replace("Click button! Count:", "Click me! Count:");
|
||||
mainContent = mainContent.replace("asset!('/assets/alternative-style.css')", "asset!('/assets/style.css')");
|
||||
fs.writeFileSync(mainPath, mainContent);
|
||||
styleContent = styleContent.replace(
|
||||
"background-color: blue;",
|
||||
"background-color: red;"
|
||||
);
|
||||
fs.writeFileSync(stylePath, styleContent);
|
||||
|
||||
await page.goto("http://localhost:9980");
|
||||
|
||||
// ** First test make sure the initial fat build is working **
|
||||
// Expect the page to contain the counter text.
|
||||
const main = page.locator("#main");
|
||||
await expect(main).toContainText("Click me! Count: 0");
|
||||
|
||||
// Click the increment button.
|
||||
let button = page.locator("button#increment-button");
|
||||
await button.click();
|
||||
|
||||
// Expect the page to contain the updated counter text.
|
||||
await expect(main).toContainText("Click me! Count: 1");
|
||||
|
||||
// Make sure the css is applied correctly.
|
||||
await expect(main).toHaveCSS("background-color", "rgb(255, 0, 0)");
|
||||
|
||||
// Make sure the image is loaded.
|
||||
const headerImage = page.locator("#toasts");
|
||||
// expect the attribute src to start with /assets/toasts-
|
||||
await expect(headerImage).toHaveAttribute("src", /\/assets\/toasts-/);
|
||||
|
||||
// ** Then make sure the hot patch is working **
|
||||
// Then change the file to increment by 2.
|
||||
const updatedContent = mainContent.replace(/num \+= 1;/g, "num += 2;");
|
||||
// Change the click me text to reflect the new increment.
|
||||
const updatedContentWithText = updatedContent.replace(
|
||||
"Click me! Count:",
|
||||
"Click button! Count:"
|
||||
);
|
||||
fs.writeFileSync(mainPath, updatedContentWithText);
|
||||
|
||||
// Wait for the page to update and show the new text.
|
||||
await expect(main).toContainText("Click button! Count: 1", hotPatchTimeout);
|
||||
|
||||
// Now click the button again.
|
||||
await button.click();
|
||||
|
||||
// Expect the count to update by 2.
|
||||
await expect(main).toContainText("Click button! Count: 3");
|
||||
|
||||
// Next change just the css file to change the background color to blue.
|
||||
const updatedStyleContent = styleContent.replace(
|
||||
"background-color: red;",
|
||||
"background-color: blue;"
|
||||
);
|
||||
fs.writeFileSync(stylePath, updatedStyleContent);
|
||||
|
||||
// Wait for the page to update the background color.
|
||||
await expect(main).toHaveCSS(
|
||||
"background-color",
|
||||
"rgb(0, 0, 255)",
|
||||
hotPatchTimeout
|
||||
);
|
||||
|
||||
// Make sure the image is still loaded.
|
||||
// expect the attribute src to start with /assets/toasts-
|
||||
await expect(headerImage).toHaveAttribute("src", /\/assets\/toasts-/);
|
||||
|
||||
// ** Then add a new asset to the page **
|
||||
// Switch from style to alternative-style
|
||||
const updatedContentWithAlternativeStyle = updatedContentWithText.replace(
|
||||
'asset!("/assets/style.css")',
|
||||
'asset!("/assets/alternative-style.css")'
|
||||
);
|
||||
fs.writeFileSync(mainPath, updatedContentWithAlternativeStyle);
|
||||
|
||||
// Assert the page has the new alternative style applied.
|
||||
const body = page.locator("body");
|
||||
// Log the page content to debug if needed.
|
||||
console.log(await page.content());
|
||||
await expect(body).toHaveCSS(
|
||||
"background-color",
|
||||
"rgb(100, 100, 100)",
|
||||
hotPatchTimeout
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user