Skip to content

Commit b3886aa

Browse files
authored
fix(testing): prevent find from throwing error when query has no match (#5641)
* fix(testing): prevent `find` from throwing error when query has no match This commit fixes an issue w/ our Puppeteer testing implementation where the `find()` method would throw an error if the query had no matching elements. Fixes: #5639 STENCIL-1256 * it likes this better * add non-shadow tests
1 parent 30d3a3c commit b3886aa

File tree

6 files changed

+119
-0
lines changed

6 files changed

+119
-0
lines changed

src/testing/puppeteer/puppeteer-element.ts

+5
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,11 @@ export async function find(page: pd.E2EPageInternal, rootHandle: puppeteer.Eleme
549549

550550
if (typeof selector === 'string' && selector.includes('>>>')) {
551551
const handle = await page.$(selector);
552+
553+
if (!handle) {
554+
return null;
555+
}
556+
552557
const elm = new E2EElement(page, handle);
553558
await elm.e2eSync();
554559
return elm;

test/end-to-end/src/components.d.ts

+26
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ export namespace Components {
3636
}
3737
interface ElementCmp {
3838
}
39+
interface EmptyCmp {
40+
}
41+
interface EmptyCmpShadow {
42+
}
3943
interface EnvData {
4044
}
4145
interface EventCmp {
@@ -187,6 +191,18 @@ declare global {
187191
prototype: HTMLElementCmpElement;
188192
new (): HTMLElementCmpElement;
189193
};
194+
interface HTMLEmptyCmpElement extends Components.EmptyCmp, HTMLStencilElement {
195+
}
196+
var HTMLEmptyCmpElement: {
197+
prototype: HTMLEmptyCmpElement;
198+
new (): HTMLEmptyCmpElement;
199+
};
200+
interface HTMLEmptyCmpShadowElement extends Components.EmptyCmpShadow, HTMLStencilElement {
201+
}
202+
var HTMLEmptyCmpShadowElement: {
203+
prototype: HTMLEmptyCmpShadowElement;
204+
new (): HTMLEmptyCmpShadowElement;
205+
};
190206
interface HTMLEnvDataElement extends Components.EnvData, HTMLStencilElement {
191207
}
192208
var HTMLEnvDataElement: {
@@ -284,6 +300,8 @@ declare global {
284300
"dom-interaction": HTMLDomInteractionElement;
285301
"dom-visible": HTMLDomVisibleElement;
286302
"element-cmp": HTMLElementCmpElement;
303+
"empty-cmp": HTMLEmptyCmpElement;
304+
"empty-cmp-shadow": HTMLEmptyCmpShadowElement;
287305
"env-data": HTMLEnvDataElement;
288306
"event-cmp": HTMLEventCmpElement;
289307
"import-assets": HTMLImportAssetsElement;
@@ -328,6 +346,10 @@ declare namespace LocalJSX {
328346
}
329347
interface ElementCmp {
330348
}
349+
interface EmptyCmp {
350+
}
351+
interface EmptyCmpShadow {
352+
}
331353
interface EnvData {
332354
}
333355
interface EventCmp {
@@ -376,6 +398,8 @@ declare namespace LocalJSX {
376398
"dom-interaction": DomInteraction;
377399
"dom-visible": DomVisible;
378400
"element-cmp": ElementCmp;
401+
"empty-cmp": EmptyCmp;
402+
"empty-cmp-shadow": EmptyCmpShadow;
379403
"env-data": EnvData;
380404
"event-cmp": EventCmp;
381405
"import-assets": ImportAssets;
@@ -408,6 +432,8 @@ declare module "@stencil/core" {
408432
"dom-interaction": LocalJSX.DomInteraction & JSXBase.HTMLAttributes<HTMLDomInteractionElement>;
409433
"dom-visible": LocalJSX.DomVisible & JSXBase.HTMLAttributes<HTMLDomVisibleElement>;
410434
"element-cmp": LocalJSX.ElementCmp & JSXBase.HTMLAttributes<HTMLElementCmpElement>;
435+
"empty-cmp": LocalJSX.EmptyCmp & JSXBase.HTMLAttributes<HTMLEmptyCmpElement>;
436+
"empty-cmp-shadow": LocalJSX.EmptyCmpShadow & JSXBase.HTMLAttributes<HTMLEmptyCmpShadowElement>;
411437
"env-data": LocalJSX.EnvData & JSXBase.HTMLAttributes<HTMLEnvDataElement>;
412438
"event-cmp": LocalJSX.EventCmp & JSXBase.HTMLAttributes<HTMLEventCmpElement>;
413439
"import-assets": LocalJSX.ImportAssets & JSXBase.HTMLAttributes<HTMLImportAssetsElement>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Component, h, Host } from '@stencil/core';
2+
3+
@Component({
4+
tag: 'empty-cmp-shadow',
5+
shadow: true,
6+
})
7+
export class EmptyComponentShadow {
8+
render() {
9+
return <Host>I have no children!</Host>;
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Component, h, Host } from '@stencil/core';
2+
3+
@Component({
4+
tag: 'empty-cmp',
5+
shadow: false,
6+
scoped: false,
7+
})
8+
export class EmptyComponent {
9+
render() {
10+
return <Host>I have no children!</Host>;
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { newE2EPage } from '@stencil/core/testing';
2+
3+
describe('Querying non-existent element(s)', () => {
4+
describe('Shadow DOM', () => {
5+
it('returns `null` if the element does not exist', async () => {
6+
// create a new puppeteer page
7+
const page = await newE2EPage({
8+
html: `
9+
<empty-cmp-shadow></empty-cmp-shadow>
10+
`,
11+
});
12+
13+
const elm = await page.find('empty-cmp-shadow >>> .non-existent');
14+
expect(elm).toBeNull();
15+
});
16+
17+
it('returns an empty array if no elements match the selector', async () => {
18+
// create a new puppeteer page
19+
const page = await newE2EPage({
20+
html: `
21+
<empty-cmp-shadow></empty-cmp-shadow>
22+
`,
23+
});
24+
25+
const elm = await page.findAll('empty-cmp-shadow >>> .non-existent');
26+
expect(elm).toEqual([]);
27+
});
28+
});
29+
30+
describe('Light DOM', () => {
31+
it('returns `null` if the element does not exist', async () => {
32+
// create a new puppeteer page
33+
const page = await newE2EPage({
34+
html: `
35+
<empty-cmp></empty-cmp>
36+
`,
37+
});
38+
39+
const elm = await page.find('empty-cmp >>> .non-existent');
40+
expect(elm).toBeNull();
41+
});
42+
43+
it('returns an empty array if no elements match the selector', async () => {
44+
// create a new puppeteer page
45+
const page = await newE2EPage({
46+
html: `
47+
<empty-cmp></empty-cmp>
48+
`,
49+
});
50+
51+
const elm = await page.findAll('empty-cmp >>> .non-existent');
52+
expect(elm).toEqual([]);
53+
});
54+
});
55+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# empty-cmp
2+
3+
4+
5+
<!-- Auto Generated Below -->
6+
7+
8+
----------------------------------------------
9+
10+
*Built with [StencilJS](https://stenciljs.com/)*

0 commit comments

Comments
 (0)