diff --git a/src/components/tree/tree.test.ts b/src/components/tree/tree.test.ts
index 2b6b766e7..66c721844 100644
--- a/src/components/tree/tree.test.ts
+++ b/src/components/tree/tree.test.ts
@@ -680,18 +680,17 @@ describe('', () => {
`);
+
const treeItems = Array.from(tree.querySelectorAll('wa-tree-item'));
// Act
await tree.updateComplete;
+ await Promise.allSettled(treeItems.map((treeItem) => treeItem.updateComplete))
// Assert
- // @TODO: Figure out why this fails in hydration
- if (fixture.type !== 'ssr-client-hydrated') {
- treeItems.forEach(treeItem => {
- expect(treeItem).to.have.attribute('selected');
- });
- }
+ treeItems.forEach(treeItem => {
+ expect(treeItem).to.have.attribute('selected');
+ });
});
});
@@ -716,14 +715,12 @@ describe('', () => {
// Act
await tree.updateComplete;
+ await Promise.allSettled(treeItems.map((treeItem) => treeItem.updateComplete))
// Assert
- // @TODO: Figure out why this fails in hydration
- if (fixture.type !== 'ssr-client-hydrated') {
- treeItems.forEach(treeItem => {
- expect(treeItem).to.have.attribute('selected');
- });
- }
+ treeItems.forEach(treeItem => {
+ expect(treeItem).to.have.attribute('selected');
+ });
expect(treeItems[0].indeterminate).to.be.false;
});
});
@@ -748,15 +745,11 @@ describe('', () => {
// Act
await tree.updateComplete;
+ await Promise.allSettled(treeItems.map((treeItem) => treeItem.updateComplete))
// Assert
expect(treeItems[0]).not.to.have.attribute('selected');
-
- // @TODO: figure out why this fails with SSR.
- if (fixture.type !== 'ssr-client-hydrated') {
- expect(treeItems[0].indeterminate).to.be.true;
- }
-
+ expect(treeItems[0].indeterminate).to.be.true;
expect(treeItems[1]).to.have.attribute('selected');
expect(treeItems[2]).not.to.have.attribute('selected');
expect(treeItems[3]).not.to.have.attribute('selected');
@@ -767,7 +760,7 @@ describe('', () => {
});
});
- // https://github.com/shoelace-style/shoelace/issues/1916
+ // // https://github.com/shoelace-style/shoelace/issues/1916
it("Should not render 'null' if it can't find a custom icon", async () => {
const tree = await fixture(html`
diff --git a/src/components/tree/tree.ts b/src/components/tree/tree.ts
index 7d2657cfb..5aee33ea2 100644
--- a/src/components/tree/tree.ts
+++ b/src/components/tree/tree.ts
@@ -141,26 +141,28 @@ export default class WaTree extends WebAwesomeElement {
// Initializes new items by setting the `selectable` property and the expanded/collapsed icons if any
private initTreeItem = (item: WaTreeItem) => {
- item.selectable = this.selection === 'multiple';
+ item.updateComplete.then(() => {
+ item.selectable = this.selection === 'multiple';
- ['expand', 'collapse']
- .filter(status => !!this.querySelector(`[slot="${status}-icon"]`))
- .forEach((status: 'expand' | 'collapse') => {
- const existingIcon = item.querySelector(`[slot="${status}-icon"]`);
- const expandButtonIcon = this.getExpandButtonIcon(status);
+ ['expand', 'collapse']
+ .filter(status => !!this.querySelector(`[slot="${status}-icon"]`))
+ .forEach((status: 'expand' | 'collapse') => {
+ const existingIcon = item.querySelector(`[slot="${status}-icon"]`);
+ const expandButtonIcon = this.getExpandButtonIcon(status);
- if (!expandButtonIcon) return;
+ if (!expandButtonIcon) return;
- if (existingIcon === null) {
- // No separator exists, add one
- item.append(expandButtonIcon);
- } else if (existingIcon.hasAttribute('data-default')) {
- // A default separator exists, replace it
- existingIcon.replaceWith(expandButtonIcon);
- } else {
- // The user provided a custom icon, leave it alone
- }
- });
+ if (existingIcon === null) {
+ // No separator exists, add one
+ item.append(expandButtonIcon);
+ } else if (existingIcon.hasAttribute('data-default')) {
+ // A default separator exists, replace it
+ existingIcon.replaceWith(expandButtonIcon);
+ } else {
+ // The user provided a custom icon, leave it alone
+ }
+ });
+ })
};
private handleTreeChanged = (mutations: MutationRecord[]) => {
@@ -359,15 +361,19 @@ export default class WaTree extends WebAwesomeElement {
this.setAttribute('aria-multiselectable', isSelectionMultiple ? 'true' : 'false');
for (const item of items) {
- item.selectable = isSelectionMultiple;
+ item.updateComplete.then(() => {
+ item.selectable = isSelectionMultiple;
+ })
}
if (isSelectionMultiple) {
await this.updateComplete;
- [...this.querySelectorAll(':scope > wa-tree-item')].forEach((treeItem: WaTreeItem) =>
- syncCheckboxes(treeItem, true)
- );
+ [...this.querySelectorAll(':scope > wa-tree-item')].forEach((treeItem: WaTreeItem) => {
+ treeItem.updateComplete.then(() => {
+ syncCheckboxes(treeItem, true)
+ })
+ });
}
}
diff --git a/src/internal/test/fixture.ts b/src/internal/test/fixture.ts
index 3dc6117f6..d7ab22a19 100644
--- a/src/internal/test/fixture.ts
+++ b/src/internal/test/fixture.ts
@@ -8,6 +8,8 @@ import { cleanupFixtures, ssrFixture as LitSSRFixture } from '@lit-labs/testing/
import type { LitElement, TemplateResult } from 'lit';
import type WebAwesomeElement from '../webawesome-element.js';
+ import { getDiffableHTML } from '@open-wc/semantic-dom-diff/get-diffable-html.js'
+
declare global {
interface Window {
clientComponents: string[];
@@ -20,16 +22,16 @@ declare global {
/**
* This will hopefully move to a library or be built into Lit. Right now this does nothing.
*/
-// function handleHydrationError(e: Event) {
-// const element = e.target as WebAwesomeElement;
-// const str = `Expected <${element.localName}> to not have hydration error.`
+function handleHydrationError(e: Event) {
+ const element = e.target as WebAwesomeElement;
+ const str = `Expected <${element.localName}> to not have hydration error.`
-// expect(false).to.equal(true, str);
-// }
+ expect(true).to.equal(false, str);
+}
// This is a non-standard event I have added to the WebAwesomeElement base class.
// https://github.com/lit/lit/discussions/4703
-// document.addEventListener('lit-hydration-error', handleHydrationError);
+document.addEventListener('lit-hydration-error', handleHydrationError);
/**
* Loads up a fixture and loads all client components
@@ -52,15 +54,16 @@ export async function hydratedFixture(templ
hydrate: true
});
+ // @ts-expect-error Assume its a lit element.
+ await hydratedElement.updateComplete
+
// This can be removed when this is fixed: https://github.com/lit/lit/issues/4709
// This forces every element to "hydrate" and then wait for an update to complete (hydration)
await Promise.allSettled(
- [...hydratedElement.querySelectorAll('*')].map(el => {
+ [...hydratedElement.querySelectorAll('*')].map(async el => {
el.removeAttribute('defer-hydration');
return el.updateComplete;
}),
- // @ts-expect-error Assume its a lit element.
- await hydratedElement.updateComplete
);
return hydratedElement;