@wdio/browser-runner 8.14.3 → 8.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -57,7 +57,7 @@ The Browser runner allows following configurations:
57
57
 
58
58
  If you test components using one of the mentioned frameworks above, you can define a preset that ensures everything is configured out of the box. This option can't be used together with `viteConfig`.
59
59
 
60
- __Type:__ `vue` | `svelte` | `solid` | `react` | `preact`<br />
60
+ __Type:__ `vue` | `svelte` | `solid` | `react` | `preact` | `stencil`<br />
61
61
  __Example:__
62
62
 
63
63
  ```js title="wdio.conf.js"
@@ -19,6 +19,7 @@ export declare const pathToFileURL: () => string;
19
19
  export declare const fileURLToPath: () => string;
20
20
  export declare const dirname: () => string;
21
21
  export declare const resolve: () => string;
22
+ export declare const download: () => string;
22
23
  export declare const sep = "/";
23
24
  export declare const start: () => void;
24
25
  export declare const install: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/browser/mock.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,aAAa;;;CAIzB,CAAA;AAED,eAAO,MAAM,iBAAiB,SAAK,CAAA;AACnC,eAAO,MAAM,eAAe,IAAK,CAAA;AACjC,qBAAa,YAAY;CAAG;AAC5B,eAAO,MAAM,GAAG;;;;;CAAa,CAAA;AAC7B,eAAO,MAAM,aAAa,cAAW,CAAA;AACrC,eAAO,MAAM,aAAa,cAAW,CAAA;AACrC,eAAO,MAAM,OAAO,cAAW,CAAA;AAC/B,eAAO,MAAM,OAAO,cAAW,CAAA;AAC/B,eAAO,MAAM,GAAG,MAAM,CAAA;AACtB,eAAO,MAAM,KAAK,YAAW,CAAA;AAC7B,eAAO,MAAM,OAAO,YAAW,CAAA;AAC/B,eAAO,MAAM,qBAAqB,YAAW,CAAA;AAC7C,eAAO,MAAM,OAAO,YAAW,CAAA;AAC/B,eAAO,MAAM,oBAAoB,YAAW,CAAA;AAC5C,eAAO,MAAM,WAAW,YAAW,CAAA;AACnC,eAAO,MAAM,cAAc,YAAW,CAAA;AACtC,eAAO,MAAM,oBAAoB,YAAW,CAAA;AAC5C,eAAO,MAAM,qBAAqB,YAAW,CAAA;AAC7C,eAAO,MAAM,IAAI,YAAY,CAAA;AAC7B,eAAO,MAAM,IAAI,YAAW,CAAA;AAC5B,eAAO,MAAM,aAAa,YAAW,CAAA;;AACrC,wBAAuB"}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/browser/mock.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,aAAa;;;CAIzB,CAAA;AAED,eAAO,MAAM,iBAAiB,SAAK,CAAA;AACnC,eAAO,MAAM,eAAe,IAAK,CAAA;AACjC,qBAAa,YAAY;CAAG;AAC5B,eAAO,MAAM,GAAG;;;;;CAAa,CAAA;AAC7B,eAAO,MAAM,aAAa,cAAW,CAAA;AACrC,eAAO,MAAM,aAAa,cAAW,CAAA;AACrC,eAAO,MAAM,OAAO,cAAW,CAAA;AAC/B,eAAO,MAAM,OAAO,cAAW,CAAA;AAC/B,eAAO,MAAM,QAAQ,cAAW,CAAA;AAChC,eAAO,MAAM,GAAG,MAAM,CAAA;AACtB,eAAO,MAAM,KAAK,YAAW,CAAA;AAC7B,eAAO,MAAM,OAAO,YAAW,CAAA;AAC/B,eAAO,MAAM,qBAAqB,YAAW,CAAA;AAC7C,eAAO,MAAM,OAAO,YAAW,CAAA;AAC/B,eAAO,MAAM,oBAAoB,YAAW,CAAA;AAC5C,eAAO,MAAM,WAAW,YAAW,CAAA;AACnC,eAAO,MAAM,cAAc,YAAW,CAAA;AACtC,eAAO,MAAM,oBAAoB,YAAW,CAAA;AAC5C,eAAO,MAAM,qBAAqB,YAAW,CAAA;AAC7C,eAAO,MAAM,IAAI,YAAY,CAAA;AAC7B,eAAO,MAAM,IAAI,YAAW,CAAA;AAC5B,eAAO,MAAM,aAAa,YAAW,CAAA;;AACrC,wBAAuB"}
@@ -15,6 +15,7 @@ export const pathToFileURL = () => '';
15
15
  export const fileURLToPath = () => '';
16
16
  export const dirname = () => '';
17
17
  export const resolve = () => '';
18
+ export const download = () => '';
18
19
  export const sep = '/';
19
20
  export const start = () => { };
20
21
  export const install = () => { };
package/build/types.d.ts CHANGED
@@ -8,7 +8,7 @@ declare global {
8
8
  wdioDebugContinue: (value: unknown) => void;
9
9
  }
10
10
  }
11
- export type FrameworkPreset = 'react' | 'preact' | 'vue' | 'svelte' | 'lit' | 'solid';
11
+ export type FrameworkPreset = 'react' | 'preact' | 'vue' | 'svelte' | 'lit' | 'solid' | 'stencil';
12
12
  type Arrayable<T> = T | Array<T>;
13
13
  type CoverageReporter = 'clover' | 'cobertura' | 'html-spa' | 'html' | 'json-summary' | 'json' | 'lcov' | 'lcovonly' | 'none' | 'teamcity' | 'text-lcov' | 'text-summary' | 'text';
14
14
  export interface CoverageOptions extends Omit<IstanbulPluginOptions, 'cypress' | 'checkProd' | 'forceBuildInstrument'> {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,WAAW,EAAE,WAAW,CAAA;QACxB,iBAAiB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAC9C;CACJ;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;AACrF,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;AAChC,KAAK,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,MAAM,CAAA;AAClL,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,WAAW,GAAG,sBAAsB,CAAC;IAClH;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAA;IACtC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC,GAAG,EAAE,SAAS,KAAK,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IAC/F;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,OAAQ,SAAQ,OAAO,CAAC,gBAAgB;IACrD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,GAAG,CAAA;IACT,GAAG,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,OAAO,CAAC,UAAU,CAAA;IAC1B,YAAY,EAAE,YAAY,CAAC,gBAAgB,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,WAAW,EAAE,WAAW,CAAA;QACxB,iBAAiB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAC9C;CACJ;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,CAAA;AACjG,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;AAChC,KAAK,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,MAAM,CAAA;AAClL,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,WAAW,GAAG,sBAAsB,CAAC;IAClH;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAA;IACtC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC,GAAG,EAAE,SAAS,KAAK,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAA;IAC/F;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,OAAQ,SAAQ,OAAO,CAAC,gBAAgB;IACrD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,GAAG,CAAA;IACT,GAAG,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,OAAO,CAAC,UAAU,CAAA;IAC1B,YAAY,EAAE,YAAY,CAAC,gBAAgB,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/vite/constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAGxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAgB1F,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,YAAY,CAkCrD,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/vite/constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAGxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAiB1F,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,YAAY,CAkCrD,CAAA"}
@@ -16,6 +16,7 @@ export const PRESET_DEPENDENCIES = {
16
16
  vue: ['@vitejs/plugin-vue', 'default', undefined],
17
17
  svelte: ['@sveltejs/vite-plugin-svelte', 'svelte', undefined],
18
18
  solid: ['vite-plugin-solid', 'default', undefined],
19
+ stencil: undefined,
19
20
  lit: undefined
20
21
  };
21
22
  export const DEFAULT_VITE_CONFIG = {
@@ -0,0 +1,71 @@
1
+ import type { NewSpecPageOptions } from '@stencil/core/internal';
2
+ interface StencilEnvironment {
3
+ /**
4
+ * After changes have been made to a component, such as a update to a property or
5
+ * attribute, the test page does not automatically apply the changes. In order to
6
+ * wait for, and apply the update, call await `flushAll()`.
7
+ */
8
+ flushAll: () => void;
9
+ }
10
+ /**
11
+ * Creates a new spec page for unit testing
12
+ * @param opts the options to apply to the spec page that influence its configuration and operation
13
+ * @returns the created spec page
14
+ */
15
+ export declare function render(opts: NewSpecPageOptions): StencilEnvironment;
16
+ /**
17
+ * A set of flags used for bitwise calculations against {@link ComponentRuntimeMeta#$flags$}.
18
+ *
19
+ * These flags should only be used in conjunction with {@link ComponentRuntimeMeta#$flags$}.
20
+ * They should _not_ be used for calculations against other fields/numbers
21
+ */
22
+ export declare const enum CMP_FLAGS {
23
+ /**
24
+ * Used to determine if a component is using the shadow DOM.
25
+ * e.g. `shadow: true | {}` is set on the `@Component()` decorator
26
+ */
27
+ shadowDomEncapsulation = 1,
28
+ /**
29
+ * Used to determine if a component is using scoped stylesheets
30
+ * e.g. `scoped: true` is set on the `@Component()` decorator
31
+ */
32
+ scopedCssEncapsulation = 2,
33
+ /**
34
+ * Used to determine if a component does not use the shadow DOM _and_ has `<slot/>` tags in its markup.
35
+ */
36
+ hasSlotRelocation = 4,
37
+ /**
38
+ * Determines if a shim for the shadow DOM is necessary.
39
+ *
40
+ * The shim should only be needed if a component requires {@link shadowDomEncapsulation} and if any output
41
+ * target-specific criteria are met. Refer to this flag's usage to determine each output target's criteria.
42
+ */
43
+ needsShadowDomShim = 8,
44
+ /**
45
+ * Determines if `delegatesFocus` is enabled for a component that uses the shadow DOM.
46
+ * e.g. `shadow: { delegatesFocus: true }` is set on the `@Component()` decorator
47
+ */
48
+ shadowDelegatesFocus = 16,
49
+ /**
50
+ * Determines if `mode` is set on the `@Component()` decorator
51
+ */
52
+ hasMode = 32,
53
+ /**
54
+ * Determines if styles must be scoped due to either:
55
+ * 1. A component is using scoped stylesheets ({@link scopedCssEncapsulation})
56
+ * 2. A component is using the shadow DOM _and_ the output target's rules for requiring a shadow DOM shim have been
57
+ * met ({@link needsShadowDomShim})
58
+ */
59
+ needsScopedEncapsulation = 10
60
+ }
61
+ /**
62
+ * Transform metadata about a component from the compiler to a compact form for
63
+ * use at runtime.
64
+ *
65
+ * @param compilerMeta component metadata gathered during compilation
66
+ * @param includeMethods include methods in the component's members or not
67
+ * @returns a compact format for component metadata, intended for runtime use
68
+ */
69
+ export declare const formatComponentRuntimeMeta: (compilerMeta: any, includeMethods: boolean) => any;
70
+ export {};
71
+ //# sourceMappingURL=stencil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stencil.d.ts","sourceRoot":"","sources":["../../../../src/vite/frameworks/fixtures/stencil.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAKR,kBAAkB,EACrB,MAAM,wBAAwB,CAAA;AAgB/B,UAAU,kBAAkB;IACxB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,IAAI,CAAA;CACvB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,CA0HnE;AAsGD;;;;;GAKG;AACH,0BAAkB,SAAS;IACvB;;;OAGG;IACH,sBAAsB,IAAS;IAC/B;;;OAGG;IACH,sBAAsB,IAAS;IAC/B;;OAEG;IACH,iBAAiB,IAAS;IAM1B;;;;;OAKG;IACH,kBAAkB,IAAS;IAC3B;;;OAGG;IACH,oBAAoB,KAAS;IAC7B;;OAEG;IACH,OAAO,KAAS;IAEhB;;;;;OAKG;IACH,wBAAwB,KAA8C;CACzE;AASD;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,iBACrB,GAAG,kBACD,OAAO,KACxB,GAyBF,CAAA"}
@@ -0,0 +1,380 @@
1
+ import { h } from '@stencil/core';
2
+ process.nextTick = (cb) => setTimeout(cb, 0);
3
+ // @ts-expect-error
4
+ window.React = {
5
+ createElement: h,
6
+ };
7
+ import { bootstrapLazy, flushAll, insertVdomAnnotations, registerComponents, registerModule, renderVdom, setSupportsShadowDom, startAutoApplyChanges, styles, win, writeTask,
8
+ // @ts-expect-error
9
+ } from '@stencil/core/internal/testing/index.js';
10
+ /**
11
+ * Creates a new spec page for unit testing
12
+ * @param opts the options to apply to the spec page that influence its configuration and operation
13
+ * @returns the created spec page
14
+ */
15
+ export function render(opts) {
16
+ if (!opts) {
17
+ throw new Error('NewSpecPageOptions required');
18
+ }
19
+ const stencilStage = document.querySelector('stencil-stage');
20
+ if (stencilStage) {
21
+ stencilStage.remove();
22
+ }
23
+ const stage = document.createElement('stencil-stage');
24
+ document.body.appendChild(stage);
25
+ if (Array.isArray(opts.components)) {
26
+ registerComponents(opts.components);
27
+ }
28
+ if (opts.hydrateClientSide) {
29
+ opts.includeAnnotations = true;
30
+ }
31
+ if (opts.hydrateServerSide) {
32
+ opts.includeAnnotations = true;
33
+ setSupportsShadowDom(false);
34
+ }
35
+ else {
36
+ opts.includeAnnotations = !!opts.includeAnnotations;
37
+ if (opts.supportsShadowDom === false) {
38
+ setSupportsShadowDom(false);
39
+ }
40
+ else {
41
+ setSupportsShadowDom(true);
42
+ }
43
+ }
44
+ const cmpTags = new Set();
45
+ const doc = win.document;
46
+ const page = {
47
+ win: win,
48
+ doc: doc,
49
+ body: stage,
50
+ styles: styles
51
+ };
52
+ const lazyBundles = opts.components.map((Cstr) => {
53
+ // eslint-disable-next-line eqeqeq
54
+ if (Cstr.COMPILER_META == null) {
55
+ throw new Error('Invalid component class: Missing static "COMPILER_META" property.');
56
+ }
57
+ cmpTags.add(Cstr.COMPILER_META.tagName);
58
+ Cstr.isProxied = false;
59
+ proxyComponentLifeCycles(Cstr);
60
+ const bundleId = `${Cstr.COMPILER_META.tagName}.${Math.round(Math.random() * 899999) + 100000}`;
61
+ const stylesMeta = Cstr.COMPILER_META.styles;
62
+ if (Array.isArray(stylesMeta)) {
63
+ if (stylesMeta.length > 1) {
64
+ const styles = {};
65
+ stylesMeta.forEach((style) => {
66
+ styles[style.modeName] = style.styleStr;
67
+ });
68
+ Cstr.style = styles;
69
+ }
70
+ else if (stylesMeta.length === 1) {
71
+ Cstr.style = stylesMeta[0].styleStr;
72
+ }
73
+ }
74
+ registerModule(bundleId, Cstr);
75
+ const lazyBundleRuntimeMeta = formatLazyBundleRuntimeMeta(bundleId, [Cstr.COMPILER_META]);
76
+ return lazyBundleRuntimeMeta;
77
+ });
78
+ if (typeof opts.direction === 'string') {
79
+ page.doc.documentElement.setAttribute('dir', opts.direction);
80
+ }
81
+ if (typeof opts.language === 'string') {
82
+ page.doc.documentElement.setAttribute('lang', opts.language);
83
+ }
84
+ bootstrapLazy(lazyBundles);
85
+ if (typeof opts.template === 'function') {
86
+ const cmpMeta = {
87
+ $flags$: 0,
88
+ $tagName$: 'body',
89
+ };
90
+ const ref = {
91
+ $ancestorComponent$: undefined,
92
+ $flags$: 0,
93
+ $modeName$: undefined,
94
+ $cmpMeta$: cmpMeta,
95
+ $hostElement$: page.body,
96
+ };
97
+ renderVdom(ref, opts.template());
98
+ }
99
+ let rootComponent = null;
100
+ Object.defineProperty(page, 'root', {
101
+ get() {
102
+ if (!rootComponent) {
103
+ rootComponent = findRootComponent(cmpTags, page.body);
104
+ }
105
+ if (rootComponent) {
106
+ return rootComponent;
107
+ }
108
+ const firstElementChild = page.body.firstElementChild;
109
+ if (!firstElementChild) {
110
+ return firstElementChild;
111
+ }
112
+ return null;
113
+ },
114
+ });
115
+ if (opts.hydrateServerSide) {
116
+ insertVdomAnnotations(doc, []);
117
+ }
118
+ if (opts.autoApplyChanges) {
119
+ startAutoApplyChanges();
120
+ }
121
+ flushAll();
122
+ return { flushAll };
123
+ }
124
+ /**
125
+ * A helper method that proxies Stencil lifecycle methods by mutating the provided component class
126
+ * @param Cstr the component class whose lifecycle methods will be proxied
127
+ */
128
+ function proxyComponentLifeCycles(Cstr) {
129
+ // we may have called this function on the class before, reset the state of the class
130
+ if (typeof Cstr.prototype?.__componentWillLoad === 'function') {
131
+ Cstr.prototype.componentWillLoad = Cstr.prototype.__componentWillLoad;
132
+ Cstr.prototype.__componentWillLoad = null;
133
+ }
134
+ if (typeof Cstr.prototype?.__componentWillUpdate === 'function') {
135
+ Cstr.prototype.componentWillUpdate = Cstr.prototype.__componentWillUpdate;
136
+ Cstr.prototype.__componentWillUpdate = null;
137
+ }
138
+ if (typeof Cstr.prototype?.__componentWillRender === 'function') {
139
+ Cstr.prototype.componentWillRender = Cstr.prototype.__componentWillRender;
140
+ Cstr.prototype.__componentWillRender = null;
141
+ }
142
+ // the class should be in a known 'good' state to proxy functions
143
+ if (typeof Cstr.prototype?.componentWillLoad === 'function') {
144
+ Cstr.prototype.__componentWillLoad = Cstr.prototype.componentWillLoad;
145
+ Cstr.prototype.componentWillLoad = function () {
146
+ // @ts-expect-error
147
+ const result = this.__componentWillLoad();
148
+ if (result && typeof result.then === 'function') {
149
+ writeTask(() => result);
150
+ }
151
+ else {
152
+ writeTask(() => Promise.resolve());
153
+ }
154
+ return result;
155
+ };
156
+ }
157
+ if (typeof Cstr.prototype?.componentWillUpdate === 'function') {
158
+ Cstr.prototype.__componentWillUpdate = Cstr.prototype.componentWillUpdate;
159
+ Cstr.prototype.componentWillUpdate = function () {
160
+ // @ts-expect-error
161
+ const result = this.__componentWillUpdate();
162
+ if (result && typeof result.then === 'function') {
163
+ writeTask(() => result);
164
+ }
165
+ else {
166
+ writeTask(() => Promise.resolve());
167
+ }
168
+ return result;
169
+ };
170
+ }
171
+ if (typeof Cstr.prototype?.componentWillRender === 'function') {
172
+ Cstr.prototype.__componentWillRender = Cstr.prototype.componentWillRender;
173
+ Cstr.prototype.componentWillRender = function () {
174
+ // @ts-expect-error
175
+ const result = this.__componentWillRender();
176
+ if (result && typeof result.then === 'function') {
177
+ writeTask(() => result);
178
+ }
179
+ else {
180
+ writeTask(() => Promise.resolve());
181
+ }
182
+ return result;
183
+ };
184
+ }
185
+ }
186
+ /**
187
+ * Return the first Element whose {@link Element#nodeName} property matches a tag found in the provided `cmpTags`
188
+ * argument.
189
+ *
190
+ * If the `nodeName` property on the element matches any of the names found in the provided `cmpTags` argument, that
191
+ * element is returned. If no match is found on the current element, the children will be inspected in a depth-first
192
+ * search manner. This process continues until either:
193
+ * - an element is found (and execution ends)
194
+ * - no element is found after an exhaustive search
195
+ *
196
+ * @param cmpTags component tag names to use in the match criteria
197
+ * @param node the node whose children are to be inspected
198
+ * @returns An element whose name matches one of the strings in the provided `cmpTags`. If no match is found, `null` is
199
+ * returned
200
+ */
201
+ function findRootComponent(cmpTags, node) {
202
+ if (node) {
203
+ const children = node.children;
204
+ const childrenLength = children.length;
205
+ for (let i = 0; i < childrenLength; i++) {
206
+ const elm = children[i];
207
+ if (cmpTags.has(elm.nodeName.toLowerCase())) {
208
+ return elm;
209
+ }
210
+ }
211
+ for (let i = 0; i < childrenLength; i++) {
212
+ const r = findRootComponent(cmpTags, children[i]);
213
+ if (r) {
214
+ return r;
215
+ }
216
+ }
217
+ }
218
+ return null;
219
+ }
220
+ const formatLazyBundleRuntimeMeta = (bundleId, cmps) => {
221
+ return [bundleId, cmps.map((cmp) => formatComponentRuntimeMeta(cmp, true))];
222
+ };
223
+ /**
224
+ * Transform metadata about a component from the compiler to a compact form for
225
+ * use at runtime.
226
+ *
227
+ * @param compilerMeta component metadata gathered during compilation
228
+ * @param includeMethods include methods in the component's members or not
229
+ * @returns a compact format for component metadata, intended for runtime use
230
+ */
231
+ export const formatComponentRuntimeMeta = (compilerMeta, includeMethods) => {
232
+ let flags = 0;
233
+ if (compilerMeta.encapsulation === 'shadow') {
234
+ flags |= 1 /* CMP_FLAGS.shadowDomEncapsulation */;
235
+ if (compilerMeta.shadowDelegatesFocus) {
236
+ flags |= 16 /* CMP_FLAGS.shadowDelegatesFocus */;
237
+ }
238
+ }
239
+ else if (compilerMeta.encapsulation === 'scoped') {
240
+ flags |= 2 /* CMP_FLAGS.scopedCssEncapsulation */;
241
+ }
242
+ if (compilerMeta.encapsulation !== 'shadow' && compilerMeta.htmlTagNames.includes('slot')) {
243
+ flags |= 4 /* CMP_FLAGS.hasSlotRelocation */;
244
+ }
245
+ if (compilerMeta.hasMode) {
246
+ flags |= 32 /* CMP_FLAGS.hasMode */;
247
+ }
248
+ const members = formatComponentRuntimeMembers(compilerMeta, includeMethods);
249
+ const hostListeners = formatHostListeners(compilerMeta);
250
+ return trimFalsy([
251
+ flags,
252
+ compilerMeta.tagName,
253
+ Object.keys(members).length > 0 ? members : undefined,
254
+ hostListeners.length > 0 ? hostListeners : undefined,
255
+ ]);
256
+ };
257
+ const formatComponentRuntimeMembers = (compilerMeta, includeMethods = true) => {
258
+ return {
259
+ ...formatPropertiesRuntimeMember(compilerMeta.properties),
260
+ ...formatStatesRuntimeMember(compilerMeta.states),
261
+ ...(includeMethods ? formatMethodsRuntimeMember(compilerMeta.methods) : {}),
262
+ };
263
+ };
264
+ const formatPropertiesRuntimeMember = (properties) => {
265
+ const runtimeMembers = {};
266
+ properties.forEach((member) => {
267
+ runtimeMembers[member.name] = trimFalsy([
268
+ /**
269
+ * [0] member type
270
+ */
271
+ formatFlags(member),
272
+ formatAttrName(member),
273
+ ]);
274
+ });
275
+ return runtimeMembers;
276
+ };
277
+ const formatFlags = (compilerProperty) => {
278
+ let type = formatPropType(compilerProperty.type);
279
+ if (compilerProperty.mutable) {
280
+ type |= 1024 /* MEMBER_FLAGS.Mutable */;
281
+ }
282
+ if (compilerProperty.reflect) {
283
+ type |= 512 /* MEMBER_FLAGS.ReflectAttr */;
284
+ }
285
+ return type;
286
+ };
287
+ const formatAttrName = (compilerProperty) => {
288
+ if (typeof compilerProperty.attribute === 'string') {
289
+ // string attr name means we should observe this attribute
290
+ if (compilerProperty.name === compilerProperty.attribute) {
291
+ // property name and attribute name are the exact same
292
+ // true value means to use the property name for the attribute name
293
+ return undefined;
294
+ }
295
+ // property name and attribute name are not the same
296
+ // so we need to return the actual string value
297
+ // example: "multiWord" !== "multi-word"
298
+ return compilerProperty.attribute;
299
+ }
300
+ // we shouldn't even observe an attribute for this property
301
+ return undefined;
302
+ };
303
+ const formatPropType = (type) => {
304
+ if (type === 'string') {
305
+ return 1 /* MEMBER_FLAGS.String */;
306
+ }
307
+ if (type === 'number') {
308
+ return 2 /* MEMBER_FLAGS.Number */;
309
+ }
310
+ if (type === 'boolean') {
311
+ return 4 /* MEMBER_FLAGS.Boolean */;
312
+ }
313
+ if (type === 'any') {
314
+ return 8 /* MEMBER_FLAGS.Any */;
315
+ }
316
+ return 16 /* MEMBER_FLAGS.Unknown */;
317
+ };
318
+ const formatStatesRuntimeMember = (states) => {
319
+ const runtimeMembers = {};
320
+ states.forEach((member) => {
321
+ runtimeMembers[member.name] = [
322
+ 32 /* MEMBER_FLAGS.State */,
323
+ ];
324
+ });
325
+ return runtimeMembers;
326
+ };
327
+ const formatMethodsRuntimeMember = (methods) => {
328
+ const runtimeMembers = {};
329
+ methods.forEach((member) => {
330
+ runtimeMembers[member.name] = [
331
+ 64 /* MEMBER_FLAGS.Method */,
332
+ ];
333
+ });
334
+ return runtimeMembers;
335
+ };
336
+ const formatHostListeners = (compilerMeta) => {
337
+ return compilerMeta.listeners.map((compilerListener) => {
338
+ const hostListener = [
339
+ computeListenerFlags(compilerListener),
340
+ compilerListener.name,
341
+ compilerListener.method,
342
+ ];
343
+ return hostListener;
344
+ });
345
+ };
346
+ const computeListenerFlags = (listener) => {
347
+ let flags = 0;
348
+ if (listener.capture) {
349
+ flags |= 2 /* LISTENER_FLAGS.Capture */;
350
+ }
351
+ if (listener.passive) {
352
+ flags |= 1 /* LISTENER_FLAGS.Passive */;
353
+ }
354
+ switch (listener.target) {
355
+ case 'document':
356
+ flags |= 4 /* LISTENER_FLAGS.TargetDocument */;
357
+ break;
358
+ case 'window':
359
+ flags |= 8 /* LISTENER_FLAGS.TargetWindow */;
360
+ break;
361
+ case 'body':
362
+ flags |= 16 /* LISTENER_FLAGS.TargetBody */;
363
+ break;
364
+ case 'parent':
365
+ flags |= 32 /* LISTENER_FLAGS.TargetParent */;
366
+ break;
367
+ }
368
+ return flags;
369
+ };
370
+ const trimFalsy = (data) => {
371
+ const arr = data;
372
+ for (let i = arr.length - 1; i >= 0; i--) {
373
+ if (arr[i]) {
374
+ break;
375
+ }
376
+ // if falsy, safe to pop()
377
+ arr.pop();
378
+ }
379
+ return arr;
380
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/vite/frameworks/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAKxC,wBAA8B,gBAAgB,CAAE,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,yBAepH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/vite/frameworks/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAMxC,wBAA8B,gBAAgB,CAAE,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,yBAmBpH"}
@@ -1,5 +1,6 @@
1
1
  import { isNuxtFramework, optimizeForNuxt } from './nuxt.js';
2
2
  import { isUsingTailwindCSS, optimizeForTailwindCSS } from './tailwindcss.js';
3
+ import { isUsingStencilJS, optimizeForStencil } from './stencil.js';
3
4
  export default async function updateViteConfig(options, config) {
4
5
  const optimizations = {};
5
6
  const rootDir = options.rootDir || config.rootDir || process.cwd();
@@ -11,5 +12,8 @@ export default async function updateViteConfig(options, config) {
11
12
  if (isTailwind) {
12
13
  Object.assign(optimizations, await optimizeForTailwindCSS(rootDir));
13
14
  }
15
+ if (isUsingStencilJS(rootDir, options)) {
16
+ Object.assign(optimizations, await optimizeForStencil(rootDir));
17
+ }
14
18
  return optimizations;
15
19
  }
@@ -0,0 +1,4 @@
1
+ import type { InlineConfig } from 'vite';
2
+ export declare function isUsingStencilJS(rootDir: string, options: WebdriverIO.BrowserRunnerOptions): boolean;
3
+ export declare function optimizeForStencil(rootDir: string): Promise<InlineConfig>;
4
+ //# sourceMappingURL=stencil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stencil.d.ts","sourceRoot":"","sources":["../../../src/vite/frameworks/stencil.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,MAAM,CAAA;AAMhD,wBAAgB,gBAAgB,CAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,oBAAoB,WAE3F;AAED,wBAAsB,kBAAkB,CAAE,OAAO,EAAE,MAAM,yBAiBxD"}
@@ -0,0 +1,65 @@
1
+ import path from 'node:path';
2
+ import url from 'node:url';
3
+ import { hasFileByExtensions } from '../utils.js';
4
+ const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
5
+ export function isUsingStencilJS(rootDir, options) {
6
+ return Boolean(options.preset === 'stencil' || hasFileByExtensions(path.join(rootDir, 'stencil.config')));
7
+ }
8
+ export async function optimizeForStencil(rootDir) {
9
+ const stencilConfig = await import(path.join(rootDir, 'stencil.config.ts')).catch(() => ({ config: {} }));
10
+ const stencilPlugins = stencilConfig.config.plugins;
11
+ const stencilOptimizations = {
12
+ plugins: [await stencilVitePlugin(rootDir)]
13
+ };
14
+ if (stencilPlugins) {
15
+ const esbuildPlugin = stencilPlugins.find((plugin) => plugin.name === 'esbuild-plugin');
16
+ if (esbuildPlugin) {
17
+ stencilOptimizations.optimizeDeps = {
18
+ include: esbuildPlugin.options.include
19
+ };
20
+ }
21
+ }
22
+ return stencilOptimizations;
23
+ }
24
+ async function stencilVitePlugin(rootDir) {
25
+ const { transpileSync } = await import('@stencil/core/compiler/stencil.js');
26
+ const stencilHelperPath = path.resolve(__dirname, 'fixtures', 'stencil.js');
27
+ return {
28
+ name: 'wdio-stencil',
29
+ enforce: 'pre',
30
+ resolveId(source) {
31
+ if (source === '@wdio/browser-runner/stencil') {
32
+ return stencilHelperPath;
33
+ }
34
+ },
35
+ transform: function (code, id) {
36
+ if (!id.includes('StencilComponent.tsx')) {
37
+ return { code };
38
+ }
39
+ const opts = {
40
+ componentExport: 'customelement',
41
+ componentMetadata: 'compilerstatic',
42
+ coreImportPath: '@stencil/core/internal/testing',
43
+ currentDirectory: rootDir,
44
+ module: 'esm',
45
+ proxy: null,
46
+ sourceMap: 'inline',
47
+ style: null,
48
+ styleImportData: 'queryparams',
49
+ target: 'es2018',
50
+ transformAliasedImportPaths: process.env.__STENCIL_TRANSPILE_PATHS__ === 'true',
51
+ };
52
+ const transpiledCode = transpileSync(code, opts);
53
+ return {
54
+ ...transpiledCode,
55
+ code: transpiledCode.code
56
+ // HTMLElement gets imported from StencilJS, but we need to use the one from the browser
57
+ .replace('extends HTMLElement {', 'extends window.HTMLElement {')
58
+ // make sure that components are exported properly
59
+ // StencilJS removes the export when componentExport is set to 'customelement'
60
+ .replace('\nconst', '\nexport const'),
61
+ inputFilePath: id
62
+ };
63
+ }
64
+ };
65
+ }
@@ -22,7 +22,7 @@ const resolvedVirtualModuleId = '\0' + virtualModuleId;
22
22
  * functionality
23
23
  */
24
24
  const MODULES_TO_MOCK = [
25
- 'import-meta-resolve', 'puppeteer-core', 'archiver', 'glob', 'devtools', 'ws', 'decamelize',
25
+ 'import-meta-resolve', 'puppeteer-core', 'archiver', 'glob', 'devtools', 'ws', 'decamelize', 'got',
26
26
  'geckodriver', 'safaridriver', 'edgedriver', '@puppeteer/browsers', 'chrome-launcher', 'wait-port'
27
27
  ];
28
28
  const POLYFILLS = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/browser-runner",
3
- "version": "8.14.3",
3
+ "version": "8.15.0",
4
4
  "description": "A WebdriverIO runner to run unit tests tests in the browser.",
5
5
  "author": "Christian Bromann <mail@bromann.dev>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browser-runner",
@@ -34,14 +34,14 @@
34
34
  "@originjs/vite-plugin-commonjs": "^1.0.3",
35
35
  "@types/istanbul-lib-source-maps": "^4.0.1",
36
36
  "@types/node": "^20.1.0",
37
- "@vitest/spy": "^0.33.0",
38
- "@wdio/globals": "8.14.3",
39
- "@wdio/local-runner": "8.14.3",
37
+ "@vitest/spy": "^0.34.1",
38
+ "@wdio/globals": "8.15.0",
39
+ "@wdio/local-runner": "8.15.0",
40
40
  "@wdio/logger": "8.11.0",
41
- "@wdio/mocha-framework": "8.14.0",
42
- "@wdio/protocols": "8.11.0",
43
- "@wdio/types": "8.14.0",
44
- "@wdio/utils": "8.14.0",
41
+ "@wdio/mocha-framework": "8.15.0",
42
+ "@wdio/protocols": "8.14.6",
43
+ "@wdio/types": "8.15.0",
44
+ "@wdio/utils": "8.15.0",
45
45
  "ast-types": "^0.14.2",
46
46
  "deepmerge-ts": "^5.0.0",
47
47
  "expect-webdriverio": "^4.2.5",
@@ -59,8 +59,8 @@
59
59
  "vite": "~4.4.6",
60
60
  "vite-plugin-istanbul": "^5.0.0",
61
61
  "vite-plugin-top-level-await": "^1.3.0",
62
- "webdriver": "8.14.3",
63
- "webdriverio": "8.14.3",
62
+ "webdriver": "8.15.0",
63
+ "webdriverio": "8.15.0",
64
64
  "ws": "^8.13.0"
65
65
  },
66
66
  "scripts": {
@@ -71,7 +71,7 @@
71
71
  },
72
72
  "devDependencies": {
73
73
  "@types/ws": "^8.5.4",
74
- "@wdio/runner": "8.14.3"
74
+ "@wdio/runner": "8.15.0"
75
75
  },
76
- "gitHead": "5229517c22d25975c0e5dd3207b307f770b87605"
76
+ "gitHead": "78e199c5ffd74bdf3a5576952c3834c29afa989f"
77
77
  }
@@ -0,0 +1,70 @@
1
+
2
+ /**
3
+ * Options pertaining to the creation and functionality of a {@link SpecPage}
4
+ */
5
+ interface RenderOptions {
6
+ /**
7
+ * An array of components to test. Component classes can be imported into the spec file, then their reference should be added to the `component` array in order to be used throughout the test.
8
+ */
9
+ components: any[];
10
+ /**
11
+ * If `false`, do not flush the render queue on initial test setup.
12
+ */
13
+ flushQueue?: boolean;
14
+ /**
15
+ * The initial JSX used to generate the test.
16
+ * Use `template` when you want to initialize a component using their properties, instead of their HTML attributes.
17
+ * It will render the specified template (JSX) into `document.body`.
18
+ */
19
+ template?: () => any;
20
+ /**
21
+ * Sets the mocked `lang` attribute on `<html>`.
22
+ */
23
+ language?: string;
24
+ /**
25
+ * Useful for debugging hydrating components client-side. Sets that the `html` option already includes annotated prerender attributes and comments.
26
+ */
27
+ hydrateClientSide?: boolean;
28
+ /**
29
+ * Useful for debugging hydrating components server-side. The output HTML will also include prerender annotations.
30
+ */
31
+ hydrateServerSide?: boolean;
32
+ /**
33
+ * Sets the mocked `document.referrer`.
34
+ */
35
+ referrer?: string;
36
+ /**
37
+ * Manually set if the mocked document supports Shadow DOM or not. Default is `true`.
38
+ */
39
+ supportsShadowDom?: boolean;
40
+ /**
41
+ * When a component is pre-rendered it includes HTML annotations, such as `s-id` attributes and `<!-t.0->` comments. This information is used by clientside hydrating. Default is `false`.
42
+ */
43
+ includeAnnotations?: boolean;
44
+ /**
45
+ * By default, any changes to component properties and attributes must `page.waitForChanges()` in order to test the updates. As an option, `autoAppluChanges` continuously flushes the queue on the background. Default is `false`.
46
+ */
47
+ autoApplyChanges?: boolean;
48
+ /**
49
+ * By default, styles are not attached to the DOM and they are not reflected in the serialized HTML.
50
+ * Setting this option to `true` will include the component's styles in the serializable output.
51
+ */
52
+ attachStyles?: boolean;
53
+ /**
54
+ * Set {@link BuildConditionals} for testing based off the metadata of the component under test.
55
+ * When `true` all `BuildConditionals` will be assigned to the global testing `BUILD` object, regardless of their
56
+ * value. When `false`, only `BuildConditionals` with a value of `true` will be assigned to the `BUILD` object.
57
+ */
58
+ strictBuild?: boolean;
59
+ }
60
+
61
+ interface StencilEnvironment {
62
+ /**
63
+ * After changes have been made to a component, such as a update to a property or
64
+ * attribute, the test page does not automatically apply the changes. In order to
65
+ * wait for, and apply the update, call await `flushAll()`.
66
+ */
67
+ flushAll: () => void
68
+ }
69
+
70
+ export function render(opts: RenderOptions): StencilEnvironment