Skip to content
9 changes: 9 additions & 0 deletions .changeset/bumpy-cycles-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'eslint-plugin-qwik': patch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your help @sashkashishka
Some packages are not affected by this change though. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only eslint? looks like these one are using qwik as dependency. I'll open a new PR with fix

'create-qwik': patch
'@builder.io/qwik-react': patch
'@builder.io/qwik-city': patch
'@builder.io/qwik': patch

'create-qwik': patch
'@builder.io/qwik-react': patch
'@builder.io/qwik-city': patch
'@builder.io/qwik': patch
---

execute cleanup cb for all component tree while calling dispose.cleanup method returned by render fn
2 changes: 1 addition & 1 deletion packages/qwik/src/core/render/dom/render.public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export const injectQContainer = (containerEl: Element) => {

function cleanupContainer(renderCtx: RenderContext, container: Element) {
const subsManager = renderCtx.$static$.$containerState$.$subsManager$;
cleanupTree(container, renderCtx.$static$, subsManager, true);
cleanupTree(container, renderCtx.$static$, subsManager, true, true);

removeContainerState(container);

Expand Down
71 changes: 67 additions & 4 deletions packages/qwik/src/core/render/dom/render.unit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -778,14 +778,37 @@ test('should clean up subscriptions after calling the returned cleanup function'
const fixture = new ElementFixture();

const spies = {
cleanupSpy: false,
cleanup: false,
};

const { cleanup } = await render(fixture.host, <CleanupComponent spies={spies} />);

cleanup();

assert.equal(spies.cleanupSpy, true);
assert.equal(spies.cleanup, true);
});

test('should clean up nested subscriptions after calling the returned cleanup function', async () => {
const fixture = new ElementFixture();

const spies = {
parentCleanup: false,
cleanup: false,
slottedCleanup: false,
};

const { cleanup } = await render(
fixture.host,
<ParentCleanupComponent spies={spies}>
<SlottedCleanupComponent spies={spies} />
</ParentCleanupComponent>
);

cleanup();

assert.equal(spies.parentCleanup, true);
assert.equal(spies.cleanup, true);
assert.equal(spies.slottedCleanup, true);
});

async function expectRendered(fixture: ElementFixture, expected: string) {
Expand Down Expand Up @@ -1045,16 +1068,56 @@ export const Hooks = component$(() => {

//////////////////////////////////////////////////////////////////////////////////////////

export const CleanupComponent = component$((props: { spies: { cleanupSpy: boolean } }) => {
interface CleanupProps {
spies: {
parentCleanup?: boolean;
cleanup?: boolean;
slottedCleanup?: boolean;
};
}

export const ParentCleanupComponent = component$((props: CleanupProps) => {
useTask$(({ cleanup }) => {
cleanup(() => {
props.spies.cleanupSpy = true;
props.spies.parentCleanup = true;
});
});

return (
<div>
<div id="parent-cleanup">true</div>
<CleanupComponent spies={props.spies}>
<Slot />
</CleanupComponent>
</div>
);
});

export const CleanupComponent = component$((props: CleanupProps) => {
useTask$(({ cleanup }) => {
cleanup(() => {
props.spies.cleanup = true;
});
});

return (
<div>
<div id="cleanup">true</div>
<Slot />
</div>
);
});

export const SlottedCleanupComponent = component$((props: CleanupProps) => {
useTask$(({ cleanup }) => {
cleanup(() => {
props.spies.slottedCleanup = true;
});
});

return (
<div>
<div id="slotted-cleanup">true</div>
</div>
);
});
Expand Down
7 changes: 4 additions & 3 deletions packages/qwik/src/core/render/dom/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1135,11 +1135,12 @@ export const cleanupTree = (
elm: Node | VirtualElement,
staticCtx: RenderStaticContext,
subsManager: SubscriptionManager,
stopSlots: boolean
stopSlots: boolean,
dispose = false
) => {
subsManager.$clearSub$(elm);
if (isQwikElement(elm)) {
if (stopSlots && elm.hasAttribute(QSlotS)) {
if (!dispose && stopSlots && elm.hasAttribute(QSlotS)) {
staticCtx.$rmSlots$.push(elm);
return;
}
Expand All @@ -1150,7 +1151,7 @@ export const cleanupTree = (
const end = isVirtualElement(elm) ? elm.close : null;
let node: Node | null | VirtualElement = elm.firstChild;
while ((node = processVirtualNodes(node))) {
cleanupTree(node!, staticCtx, subsManager, true);
cleanupTree(node!, staticCtx, subsManager, true, dispose);
node = node.nextSibling;
if (node === end) {
break;
Expand Down
7 changes: 6 additions & 1 deletion starters/apps/starter-partytown-test/src/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ export default () => {
<head>
<meta charset="utf-8" />
<title>Qwik + Partytown Blank App</title>
<script dangerouslySetInnerHTML={partytownSnippet({ debug: true })} />
<script
dangerouslySetInnerHTML={partytownSnippet({
fallbackTimeout: 1000,
debug: true,
})}
/>
</head>
<body>
<App />
Expand Down
8 changes: 5 additions & 3 deletions starters/e2e/e2e.attributes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,13 @@ test.describe("attributes", () => {
test.describe("client rerender", () => {
test.beforeEach(async ({ page }) => {
const toggleRender = page.locator("#force-rerender");
const renderCount = page.locator("#renderCount");
const v = Number(await toggleRender.getAttribute("data-v"));

expect(v).toBe(0);
await expect(renderCount).toHaveText(`Render ${v}`);
await toggleRender.click();
await expect(page.locator("#renderCount")).toHaveText(`Render ${v}`);
// Without this the tests still fail?
await page.waitForTimeout(50);
await expect(renderCount).toHaveText(`Render ${v + 1}`);
});
tests();
});
Expand Down
1 change: 0 additions & 1 deletion starters/e2e/e2e.context.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ test.describe("context", () => {
test.beforeEach(async ({ page }) => {
const rerender = page.locator("#btn-rerender");
await rerender.click();
await page.waitForTimeout(100);
});
tests();
});
Expand Down
6 changes: 5 additions & 1 deletion starters/e2e/e2e.style.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ test.describe("styles", () => {
test.describe("client side", () => {
test.beforeEach(async ({ page }) => {
const reload = page.locator("#reload");
const renderCount = page.locator("#renderCount");
const v = Number(await reload.getAttribute("v"));

expect(v).toBe(0);
await expect(renderCount).toHaveText(`Render ${v}`);
await reload.click();
await expect(page.locator("#renderCount")).toHaveText(`Render ${v}`);
await expect(renderCount).toHaveText(`Render ${v + 1}`);
});
runTests();
});
Expand Down
2 changes: 0 additions & 2 deletions starters/e2e/qwikcity/nav.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ test.describe("actions", () => {

const link = page.locator("#hash-1");
await link.click();
// Without this, sometimes the URL is #hash-1
await page.waitForTimeout(100);

await expect(page).toHaveURL(
"/qwikcity-test/scroll-restoration/hash/#hash-2",
Expand Down
8 changes: 6 additions & 2 deletions starters/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ expect.extend({

const config: PlaywrightTestConfig = {
use: {
launchOptions: {
slowMo: 100,
},
viewport: {
width: 520,
height: 600,
Expand All @@ -27,8 +30,9 @@ const config: PlaywrightTestConfig = {
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
testIgnore: /.*example.spec.tsx?$/,
retries: inGithubCI ? 0 : 1,
expect: { timeout: inGithubCI ? 120000 : 10000 },
retries: 0,
// retries: inGithubCI ? 0 : 1,
expect: { timeout: inGithubCI ? 120000 : 3000 },
webServer: {
command:
"pnpm node --require ./scripts/runBefore.ts starters/dev-server.ts 3301",
Expand Down
Loading