Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/runtime/bootstrap-custom-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ export const proxyCustomElement = (Cstr: any, compactMeta: d.ComponentRuntimeMet

// TODO(STENCIL-914): this check and `else` block can go away and be replaced by just the `scoped` check
if (BUILD.experimentalSlotFixes) {
if (BUILD.scoped && cmpMeta.$flags$ & CMP_FLAGS.scopedCssEncapsulation) {
// This check is intentionally not combined with the surrounding `experimentalSlotFixes` check
// since, moving forward, we only want to patch the pseudo shadow DOM when the component is scoped
if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation)) {
patchPseudoShadowDom(Cstr.prototype);
}
} else {
Expand Down
4 changes: 1 addition & 3 deletions src/runtime/bootstrap-lazy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ export const bootstrapLazy = (lazyBundles: d.LazyBundlesRuntimeData, options: d.

// TODO(STENCIL-914): this check and `else` block can go away and be replaced by just the `scoped` check
if (BUILD.experimentalSlotFixes) {
// This check is intentionally not combined with the surrounding `experimentalSlotFixes` check
// since, moving forward, we only want to patch the pseudo shadow DOM when the component is scoped
if (BUILD.scoped && cmpMeta.$flags$ & CMP_FLAGS.scopedCssEncapsulation) {
if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation)) {
patchPseudoShadowDom(HostElement.prototype);
}
} else {
Expand Down
7 changes: 7 additions & 0 deletions src/runtime/dom-extras.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,13 @@ function patchHostOriginalAccessor(
accessorName: (typeof validElementPatches)[number] | (typeof validNodesPatches)[number],
node: Node,
) {
/**
* skip this method if a component was imported from a non-browser environment
*/
if (!globalThis.Node || !globalThis.Element) {
return;
}

let accessor;
if (validElementPatches.includes(accessorName as any)) {
accessor = Object.getOwnPropertyDescriptor(Element.prototype, accessorName);
Expand Down
5 changes: 4 additions & 1 deletion test/end-to-end/src/dom-api/dom-api.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,14 @@ describe('dom api e2e tests', () => {
await page.waitForChanges();

expect(elm).toEqualText(`
updated text content
dom apiupdated text content
`);

expect(elm).toEqualHtml(`
<dom-api custom-hydrate-flag="">
<span class="blue green red" data-a="a" data-z="z">
dom api
</span>
updated text content
</dom-api>
`);
Expand Down
6 changes: 4 additions & 2 deletions test/wdio/computed-properties-prop-decorator/cmp.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Fragment, h } from '@stencil/core';
import { render } from '@wdio/browser-runner/stencil';
import { $, expect } from '@wdio/globals';

describe('computed-properties-prop-decorator', () => {
beforeEach(async () => {
render({
components: [],
template: () => (
<>
<computed-properties-prop-decorator></computed-properties-prop-decorator>
Expand All @@ -22,12 +24,12 @@ describe('computed-properties-prop-decorator', () => {
});

it('correctly sets computed property `@Prop()`s and triggers re-renders', async () => {
await expect($('computed-properties-prop-decorator')).toHaveText('no content');
await expect($('computed-properties-prop-decorator').$('div')).toHaveText('no content');

const button = $('button');
await button.click();

await expect($('computed-properties-prop-decorator')).toHaveText('These are my props');
await expect($('computed-properties-prop-decorator').$('div')).toHaveText('These are my props');
});

it('has the default value reflected to the correct attribute on the host', async () => {
Expand Down
8 changes: 5 additions & 3 deletions test/wdio/computed-properties-state-decorator/cmp.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Fragment, h } from '@stencil/core';
import { render } from '@wdio/browser-runner/stencil';
import { $, expect } from '@wdio/globals';

describe('computed-properties-state-decorator', () => {
beforeEach(async () => {
render({
components: [],
template: () => (
<>
<computed-properties-state-decorator></computed-properties-state-decorator>
Expand All @@ -18,14 +20,14 @@ describe('computed-properties-state-decorator', () => {
});

it('correctly sets computed property `@State()`s and triggers re-renders', async () => {
const el: HTMLElement = document.querySelector('computed-properties-state-decorator');
await expect($(el)).toHaveText(['Has rendered: false', 'Mode: default'].join('\n'));
const el = $('computed-properties-state-decorator').$('div');
await expect(el).toHaveText(['Has rendered: false', 'Mode: default'].join('\n'));

const button = document.querySelector('button');
expect(button).toBeDefined();

await $(button).click();

await expect($(el)).toHaveText(['Has rendered: true', 'Mode: super'].join('\n'));
await expect(el).toHaveText(['Has rendered: true', 'Mode: super'].join('\n'));
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Fragment, h } from '@stencil/core';
import { render } from '@wdio/browser-runner/stencil';
import { $, expect } from '@wdio/globals';

describe('computed-properties-watch-decorator', () => {
beforeEach(async () => {
render({
components: [],
template: () => (
<>
<computed-properties-watch-decorator></computed-properties-watch-decorator>
Expand All @@ -19,7 +21,7 @@ describe('computed-properties-watch-decorator', () => {
});

it('triggers the watch callback when the associated prop changes', async () => {
const el = document.querySelector('computed-properties-watch-decorator');
const el = $('computed-properties-watch-decorator').$('div');
await expect(el).toHaveText(['First name called with: not yet', 'Last name called with: not yet'].join('\n'));

const button = document.querySelector('button');
Expand Down
6 changes: 3 additions & 3 deletions test/wdio/dom-reattach/cmp-root.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, h, Host, Prop } from '@stencil/core';
import { Component, h, Prop } from '@stencil/core';

@Component({
tag: 'dom-reattach',
Expand All @@ -22,11 +22,11 @@ export class DomReattach {

render() {
return (
<Host>
<div>
<p>componentWillLoad: {this.willLoad}</p>
<p>componentDidLoad: {this.didLoad}</p>
<p>disconnectedCallback: {this.didUnload}</p>
</Host>
</div>
);
}
}
11 changes: 6 additions & 5 deletions test/wdio/dom-reattach/cmp.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,19 @@ describe('dom-reattach', function () {
componentDidLoad: 1
disconnectedCallback: ${disconnectCount}`;

await expect($('dom-reattach')).toHaveText(lifecycleTextWithDisconnectCount(0));
const $cmp = $('dom-reattach').$('div');
await expect($cmp).toHaveText(lifecycleTextWithDisconnectCount(0));

await $('button').click();
await expect($('dom-reattach')).not.toExist();
await expect($cmp).not.toExist();

await $('button').click();
await expect($('dom-reattach')).toHaveText(lifecycleTextWithDisconnectCount(1));
await expect($cmp).toHaveText(lifecycleTextWithDisconnectCount(1));

await $('button').click();
await expect($('dom-reattach')).not.toExist();
await expect($cmp).not.toExist();

await $('button').click();
await expect($('dom-reattach')).toHaveText(lifecycleTextWithDisconnectCount(2));
await expect($cmp).toHaveText(lifecycleTextWithDisconnectCount(2));
});
});
8 changes: 5 additions & 3 deletions test/wdio/dynamic-imports/cmp.test.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { h } from '@stencil/core';
import { render } from '@wdio/browser-runner/stencil';
import { $, expect } from '@wdio/globals';

import type { DynamicImport } from './dynamic-import.js';

describe('tag-names', () => {
beforeEach(() => {
render({
components: [],
template: () => <dynamic-import></dynamic-import>,
});
});

it('should load content from dynamic import', async () => {
await expect($('dynamic-import')).toHaveText('1 hello1 world1');
await expect($('dynamic-import').$('div')).toHaveText('1 hello1 world1');

const dynamicImport = document.querySelector('dynamic-import') as HTMLElement & DynamicImport;
const dynamicImport = document.querySelector('dynamic-import') as unknown as HTMLElement & DynamicImport;
dynamicImport.update();

await expect($('dynamic-import')).toHaveText('2 hello2 world2');
await expect($('dynamic-import').$('div')).toHaveText('2 hello2 world2');
});
});
9 changes: 6 additions & 3 deletions test/wdio/external-imports/cmp.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Fragment, h } from '@stencil/core';
import { render } from '@wdio/browser-runner/stencil';
import { $, expect } from '@wdio/globals';

describe('external-imports', () => {
beforeEach(async () => {
render({
components: [],
template: () => (
<>
<external-import-a></external-import-a>
Expand All @@ -13,14 +15,15 @@ describe('external-imports', () => {
),
});
});

it('render all components without errors', async () => {
const elm = $('external-import-a');
const elm = $('external-import-a').$('div');
await expect(elm).toHaveText('Marty McFly');

const elm2 = $('external-import-b');
const elm2 = $('external-import-b').$('div');
await expect(elm2).toHaveText('Marty McFly');

const elm3 = $('external-import-c');
const elm3 = $('external-import-c').$('div');
await expect(elm3).toHaveText('Marty McFly');
});
});
36 changes: 36 additions & 0 deletions test/wdio/radio-group-blur/cmp.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { h } from '@stencil/core';
import { render } from '@wdio/browser-runner/stencil';
import { $, $$, browser, expect } from '@wdio/globals';

describe('radio-group-blur', function () {
beforeEach(async () => {
render({
components: [],
template: () => <radio-group-blur-test></radio-group-blur-test>,
});
await browser.pause(100);
});

it('should not emit blur event when focusing radio in radio group with slot', async () => {
await expect($('#blur-count')).toHaveText('0');
await $('ion-radio').click();
await expect($('#blur-count')).toHaveText('0');
});

it('should allow blur events after fast focus change', async () => {
await browser.waitUntil(
async () => {
const [radio1, radio2] = await $$('ion-radio');
return radio1 && radio2;
},
{
timeout: 5000,
timeoutMsg: 'Radio elements not found',
},
);
const [radio1, radio2] = await $$('ion-radio');
await radio1.click();
await radio2.click();
await expect($('#blur-count')).toHaveText('1');
});
});
41 changes: 41 additions & 0 deletions test/wdio/radio-group-blur/cmp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Component, Element, h, State } from '@stencil/core';

@Component({
tag: 'radio-group-blur-test',
})
export class RadioGroupBlurTest {
@Element() el: HTMLElement;
@State() blurCount = 0;

componentDidLoad = () => {
setTimeout(() => {
// The issue: blue is called on focus of the first radio only reproduces
// when the radios are dynamically added with a timeout
const radioGroup = document.getElementById('radio-group');
for (let i = 0; i < 3; i++) {
const radio = document.createElement('ion-radio');
radio.value = `radio-${i}`;
radio.textContent = `Radio ${i}`;
radioGroup?.appendChild(radio);
}
}, 100);

// listen for radio `ionBlur` on all radios
document.addEventListener('ionBlur', () => {
this.blurCount++;
});
};

render() {
return (
<div>
<h1>Radio Group Blur Test</h1>
<p>
Blur Count: <span id="blur-count">{this.blurCount}</span>
</p>

<ion-radio-group id="radio-group"></ion-radio-group>
</div>
);
}
}
11 changes: 11 additions & 0 deletions test/wdio/radio-group-blur/radio-group.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ion-radio-group {
display: block;
}

.helper-text {
display: block;
}

.error-text {
display: none;
}
Loading
Loading