create-wdio 9.0.0 → 9.17.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.
Files changed (83) hide show
  1. package/README.md +12 -7
  2. package/assets/demo.gif +0 -0
  3. package/build/cli/config.d.ts +51 -0
  4. package/build/cli/config.d.ts.map +1 -0
  5. package/build/cli/install.d.ts +12 -0
  6. package/build/cli/install.d.ts.map +1 -0
  7. package/build/cli/utils.d.ts +18 -0
  8. package/build/cli/utils.d.ts.map +1 -0
  9. package/build/config/cli.d.ts +2 -0
  10. package/build/config/cli.d.ts.map +1 -0
  11. package/build/config/cli.js +1632 -0
  12. package/build/constants.d.ts +248 -0
  13. package/build/constants.d.ts.map +1 -0
  14. package/build/index.d.ts +4 -0
  15. package/build/index.d.ts.map +1 -0
  16. package/build/index.js +1018 -54
  17. package/build/install/cli.d.ts +2 -0
  18. package/build/install/cli.d.ts.map +1 -0
  19. package/build/install/cli.js +1719 -0
  20. package/build/install.d.ts +4 -0
  21. package/build/install.d.ts.map +1 -0
  22. package/build/templates/EjsHelpers.d.ts +18 -0
  23. package/build/templates/EjsHelpers.d.ts.map +1 -0
  24. package/build/templates/exampleFiles/browser/Component.css.ejs +121 -0
  25. package/build/templates/exampleFiles/browser/Component.lit.ejs +154 -0
  26. package/build/templates/exampleFiles/browser/Component.lit.test.ejs +24 -0
  27. package/build/templates/exampleFiles/browser/Component.preact.ejs +28 -0
  28. package/build/templates/exampleFiles/browser/Component.preact.test.ejs +59 -0
  29. package/build/templates/exampleFiles/browser/Component.react.ejs +29 -0
  30. package/build/templates/exampleFiles/browser/Component.react.test.ejs +58 -0
  31. package/build/templates/exampleFiles/browser/Component.solid.ejs +28 -0
  32. package/build/templates/exampleFiles/browser/Component.solid.test.ejs +58 -0
  33. package/build/templates/exampleFiles/browser/Component.stencil.ejs +43 -0
  34. package/build/templates/exampleFiles/browser/Component.stencil.test.ejs +45 -0
  35. package/build/templates/exampleFiles/browser/Component.svelte.ejs +47 -0
  36. package/build/templates/exampleFiles/browser/Component.svelte.test.ejs +58 -0
  37. package/build/templates/exampleFiles/browser/Component.vue.ejs +34 -0
  38. package/build/templates/exampleFiles/browser/Component.vue.test.ejs +62 -0
  39. package/build/templates/exampleFiles/browser/standalone.test.ejs +13 -0
  40. package/build/templates/exampleFiles/cucumber/features/login.feature +12 -0
  41. package/build/templates/exampleFiles/cucumber/step_definitions/steps.js.ejs +55 -0
  42. package/build/templates/exampleFiles/mochaJasmine/test.e2e.js.ejs +11 -0
  43. package/build/templates/exampleFiles/pageobjects/login.page.js.ejs +45 -0
  44. package/build/templates/exampleFiles/pageobjects/page.js.ejs +17 -0
  45. package/build/templates/exampleFiles/pageobjects/secure.page.js.ejs +20 -0
  46. package/build/templates/exampleFiles/serenity-js/common/config/serenity.properties.ejs +1 -0
  47. package/build/templates/exampleFiles/serenity-js/common/serenity/github-api/GitHubStatus.ts.ejs +41 -0
  48. package/build/templates/exampleFiles/serenity-js/common/serenity/todo-list-app/TodoList.ts.ejs +100 -0
  49. package/build/templates/exampleFiles/serenity-js/common/serenity/todo-list-app/TodoListItem.ts.ejs +36 -0
  50. package/build/templates/exampleFiles/serenity-js/cucumber/step-definitions/steps.ts.ejs +37 -0
  51. package/build/templates/exampleFiles/serenity-js/cucumber/support/parameter.config.ts.ejs +18 -0
  52. package/build/templates/exampleFiles/serenity-js/cucumber/todo-list/completing_items.feature.ejs +23 -0
  53. package/build/templates/exampleFiles/serenity-js/cucumber/todo-list/narrative.md.ejs +17 -0
  54. package/build/templates/exampleFiles/serenity-js/jasmine/example.spec.ts.ejs +86 -0
  55. package/build/templates/exampleFiles/serenity-js/mocha/example.spec.ts.ejs +88 -0
  56. package/build/templates/snippets/afterTest.ejs +20 -0
  57. package/build/templates/snippets/capabilities.ejs +57 -0
  58. package/build/templates/snippets/cucumber.ejs +50 -0
  59. package/build/templates/snippets/electronTest.js.ejs +7 -0
  60. package/build/templates/snippets/jasmine.ejs +20 -0
  61. package/build/templates/snippets/macosTest.js.ejs +11 -0
  62. package/build/templates/snippets/mocha.ejs +14 -0
  63. package/build/templates/snippets/reporters.ejs +14 -0
  64. package/build/templates/snippets/serenity.ejs +18 -0
  65. package/build/templates/snippets/services.ejs +18 -0
  66. package/build/templates/snippets/testWithPO.js.ejs +22 -0
  67. package/build/templates/snippets/testWithoutPO.js.ejs +19 -0
  68. package/build/templates/snippets/vscodeTest.js.ejs +9 -0
  69. package/build/templates/wdio.conf.tpl.ejs +412 -0
  70. package/build/types.d.ts +99 -0
  71. package/build/types.d.ts.map +1 -0
  72. package/build/utils/index.d.ts +2 -0
  73. package/build/utils/index.d.ts.map +1 -0
  74. package/build/utils/index.js +849 -0
  75. package/build/utils.d.ts +78 -0
  76. package/build/utils.d.ts.map +1 -0
  77. package/package.json +60 -41
  78. package/.eslintrc.cjs +0 -37
  79. package/__mocks__/commander.ts +0 -18
  80. package/build/constants.js +0 -51
  81. package/build/types.js +0 -1
  82. package/build/utils.js +0 -38
  83. package/vitest.config.ts +0 -23
@@ -0,0 +1,4 @@
1
+ import type { PACKAGE_MANAGER } from './constants.js';
2
+ export declare function installPackages(cwd: string, packages: string[], dev: boolean): Promise<boolean>;
3
+ export declare function getInstallCommand(pm: PACKAGE_MANAGER, packages: string[], dev: boolean): string;
4
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAgBrD,wBAAsB,eAAe,CAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,oBAwBnF;AAED,wBAAgB,iBAAiB,CAAE,EAAE,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,UAGvF"}
@@ -0,0 +1,18 @@
1
+ export interface EjsHelpersConfig {
2
+ useEsm?: boolean;
3
+ useTypeScript?: boolean;
4
+ }
5
+ export declare class EjsHelpers {
6
+ readonly useTypeScript: boolean;
7
+ readonly useEsm: boolean;
8
+ constructor(config: EjsHelpersConfig);
9
+ if(condition: boolean, trueValue: string, falseValue?: string): string;
10
+ ifTs: (trueValue: string, falseValue?: string) => string;
11
+ ifEsm: (trueValue: string, falseValue?: string) => string;
12
+ param(name: string, type: string): string;
13
+ returns(type: string): string;
14
+ import(exports: string, moduleId: string): string;
15
+ private modulePathFrom;
16
+ export(keyword: 'class' | 'function' | 'const' | 'let', name: string): string;
17
+ }
18
+ //# sourceMappingURL=EjsHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EjsHelpers.d.ts","sourceRoot":"","sources":["../../src/templates/EjsHelpers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,qBAAa,UAAU;IACnB,SAAgB,aAAa,EAAE,OAAO,CAAA;IACtC,SAAgB,MAAM,EAAE,OAAO,CAAA;gBAEnB,MAAM,EAAE,gBAAgB;IAKpC,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAW;IAMjE,IAAI,GAAI,WAAW,MAAM,EAAE,aAAY,MAAW,YACI;IAEtD,KAAK,GAAI,WAAW,MAAM,EAAE,aAAY,MAAW,YACJ;IAE/C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAMhC,OAAO,CAAC,IAAI,EAAE,MAAM;IAMpB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAkBxC,OAAO,CAAC,cAAc;IAYtB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM;CAevE"}
@@ -0,0 +1,121 @@
1
+ :root {
2
+ font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
3
+ font-size: 16px;
4
+ line-height: 24px;
5
+ font-weight: 400;
6
+ text-align: center;
7
+
8
+ color-scheme: light dark;
9
+ color: rgba(255, 255, 255, 0.87);
10
+ background-color: #242424;
11
+
12
+ font-synthesis: none;
13
+ text-rendering: optimizeLegibility;
14
+ -webkit-font-smoothing: antialiased;
15
+ -moz-osx-font-smoothing: grayscale;
16
+ -webkit-text-size-adjust: 100%;
17
+ }
18
+
19
+ a {
20
+ font-weight: 500;
21
+ color: #EA5906;
22
+ text-decoration: inherit;
23
+ }
24
+
25
+ a:hover {
26
+ color: #EA5906;
27
+ }
28
+
29
+ body {
30
+ margin: 0;
31
+ display: flex;
32
+ place-items: center;
33
+ min-width: 320px;
34
+ min-height: 100vh;
35
+ }
36
+
37
+ h1 {
38
+ font-size: 3.2em;
39
+ line-height: 1.1;
40
+ }
41
+
42
+ button {
43
+ border-radius: 8px;
44
+ border: 1px solid transparent;
45
+ padding: 0.6em 1.2em;
46
+ font-size: 1em;
47
+ font-weight: 500;
48
+ font-family: inherit;
49
+ background-color: #1a1a1a;
50
+ cursor: pointer;
51
+ transition: border-color 0.25s;
52
+ }
53
+
54
+ button:hover {
55
+ border-color: #EA5906;
56
+ }
57
+
58
+ button:focus,
59
+ button:focus-visible {
60
+ outline: 4px auto -webkit-focus-ring-color;
61
+ }
62
+
63
+ @media (prefers-color-scheme: light) {
64
+ :root {
65
+ color: #213547;
66
+ background-color: #ffffff;
67
+ }
68
+
69
+ a:hover {
70
+ color: #EA590633;
71
+ }
72
+
73
+ button {
74
+ background-color: #f9f9f9;
75
+ }
76
+ }
77
+
78
+ #root {
79
+ max-width: 1280px;
80
+ margin: 0 auto;
81
+ padding: 2rem;
82
+ text-align: center;
83
+ }
84
+
85
+ .logo {
86
+ height: 12em;
87
+ padding: 1.5em;
88
+ will-change: filter;
89
+ }
90
+
91
+ .logo:hover {
92
+ filter: drop-shadow(0 0 2em #EA5906aa);
93
+ }
94
+
95
+ .logo.react:hover {
96
+ filter: drop-shadow(0 0 2em #61dafbaa);
97
+ }
98
+
99
+ @keyframes logo-spin {
100
+ from {
101
+ transform: rotate(0deg);
102
+ }
103
+
104
+ to {
105
+ transform: rotate(360deg);
106
+ }
107
+ }
108
+
109
+ @media (prefers-reduced-motion: no-preference) {
110
+ a:nth-of-type(2) .logo {
111
+ animation: logo-spin infinite 20s linear;
112
+ }
113
+ }
114
+
115
+ .card {
116
+ padding: 2em;
117
+ }
118
+
119
+ .read-the-docs {
120
+ color: #888;
121
+ }
@@ -0,0 +1,154 @@
1
+ import { LitElement, css, html } from 'lit'
2
+ <%- answers.isUsingTypeScript ? `import { customElement, property } from 'lit/decorators.js'\n` : ''
3
+ %>
4
+ /**
5
+ * An example element.
6
+ *
7
+ * @slot - This element has a slot
8
+ * @csspart button - The button
9
+ */
10
+ <%- answers.isUsingTypeScript ? `@customElement('my-element')\n` : ''
11
+ %>export class MyElement extends LitElement {<%
12
+ if (answers.isUsingTypeScript) { %>
13
+ /**
14
+ * Copy for the read the docs hint.
15
+ */
16
+ @property()
17
+ docsHint = 'Click on the WebdriverIO logo to learn more!'
18
+
19
+ /**
20
+ * The number of times the button has been clicked.
21
+ */
22
+ @property({ type: Number })
23
+ count = 0
24
+ <% } else { %>
25
+ static get properties() {
26
+ return {
27
+ /**
28
+ * Copy for the read the docs hint.
29
+ */
30
+ docsHint: { type: String },
31
+
32
+ /**
33
+ * The number of times the button has been clicked.
34
+ */
35
+ count: { type: Number },
36
+ }
37
+ }
38
+
39
+ constructor() {
40
+ super()
41
+ this.docsHint = 'Click on the WebdriverIO logo to learn more!'
42
+ this.count = 0
43
+ }
44
+ <% } %>
45
+ render() {
46
+ return html`
47
+ <div>
48
+ <a href="https://webdriver.io/docs/component-testing" target="_blank">
49
+ <img src="https://webdriver.io/assets/images/robot-3677788dd63849c56aa5cb3f332b12d5.svg" className="logo"
50
+ alt="WebdriverIO logo" />
51
+ </a>
52
+ </div>
53
+ <h1>
54
+ <slot></slot>
55
+ </h1>
56
+ <div class="card">
57
+ <button @click=${this._onClick} part="button">
58
+ count is ${this.count}
59
+ </button>
60
+ <p>
61
+ Edit <code>src/Component.test.<%- answers.isUsingTypeScript ? `ts` : 'js' %></code> and save to test HMR
62
+ </p>
63
+ </div>
64
+ <p class="read-the-docs">${this.docsHint}</p>
65
+ `
66
+ }
67
+
68
+ <%- answers.isUsingTypeScript ? `private ` : ''%>_onClick() {
69
+ this.count++
70
+ }
71
+
72
+ <% if (answers.isUsingTypeScript) { %>static styles = css`<% } else { %>static get styles() {
73
+ return css`<% } %>
74
+ :host {
75
+ max-width: 1280px;
76
+ margin: 0 auto;
77
+ padding: 2rem;
78
+ text-align: center;
79
+ }
80
+
81
+ .logo {
82
+ height: 6em;
83
+ padding: 1.5em;
84
+ will-change: filter;
85
+ transition: filter 300ms;
86
+ }
87
+ .logo:hover {
88
+ filter: drop-shadow(0 0 2em #646cffaa);
89
+ }
90
+ .logo.lit:hover {
91
+ filter: drop-shadow(0 0 2em #325cffaa);
92
+ }
93
+
94
+ .card {
95
+ padding: 2em;
96
+ }
97
+
98
+ .read-the-docs {
99
+ color: #888;
100
+ }
101
+
102
+ h1 {
103
+ font-size: 3.2em;
104
+ line-height: 1.1;
105
+ }
106
+
107
+ a {
108
+ font-weight: 500;
109
+ color: #646cff;
110
+ text-decoration: inherit;
111
+ }
112
+ a:hover {
113
+ color: #535bf2;
114
+ }
115
+
116
+ button {
117
+ border-radius: 8px;
118
+ border: 1px solid transparent;
119
+ padding: 0.6em 1.2em;
120
+ font-size: 1em;
121
+ font-weight: 500;
122
+ font-family: inherit;
123
+ background-color: #1a1a1a;
124
+ cursor: pointer;
125
+ transition: border-color 0.25s;
126
+ }
127
+ button:hover {
128
+ border-color: #646cff;
129
+ }
130
+ button:focus,
131
+ button:focus-visible {
132
+ outline: 4px auto -webkit-focus-ring-color;
133
+ }
134
+
135
+ @media (prefers-color-scheme: light) {
136
+ a:hover {
137
+ color: #747bff;
138
+ }
139
+ button {
140
+ background-color: #f9f9f9;
141
+ }
142
+ }
143
+ `
144
+ <% if (!answers.isUsingTypeScript) { %>}<% } %>
145
+ }
146
+ <% if (answers.isUsingTypeScript) { %>
147
+ declare global {
148
+ interface HTMLElementTagNameMap {
149
+ 'my-element': MyElement
150
+ }
151
+ }<%
152
+ } else { %>
153
+ window.customElements.define('my-element', MyElement)<%
154
+ } %>
@@ -0,0 +1,24 @@
1
+ import { html, render } from 'lit'
2
+ import { $, expect } from '@wdio/globals'
3
+
4
+ import './Component.js'
5
+ import './Component.css'
6
+
7
+ describe('Lit component testing', () => {
8
+ it('should increment value on click', async () => {
9
+ render(
10
+ html`<my-element id="root">WebdriverIO Component Testing</my-element>`,
11
+ document.body
12
+ )
13
+
14
+ const button = await $('my-element').$('button')
15
+ await expect(button).toHaveText('count is 0')
16
+
17
+ await button.click()
18
+ await button.click()
19
+
20
+ await expect(button).toHaveText('count is 2')<%-
21
+ answers.includeVisualTesting ? `
22
+ await expect(button).toMatchElementSnapshot('counterButton')` : '' %>
23
+ })
24
+ })
@@ -0,0 +1,28 @@
1
+ import { useState } from 'preact/hooks'
2
+ import './Component.css'
3
+
4
+ export default function ExampleComponent () {
5
+ const [count, setCount] = useState(0)
6
+
7
+ return (
8
+ <>
9
+ <div>
10
+ <a href="https://webdriver.io/docs/component-testing" target="_blank">
11
+ <img src="https://webdriver.io/assets/images/robot-3677788dd63849c56aa5cb3f332b12d5.svg" className="logo" alt="WebdriverIO logo" />
12
+ </a>
13
+ </div>
14
+ <h1>WebdriverIO Component Testing</h1>
15
+ <div class="card">
16
+ <button onClick={() => setCount((count) => count + 1)}>
17
+ count is {count}
18
+ </button>
19
+ <p>
20
+ Edit <code>src/Component.test.<%- answers.isUsingTypeScript ? `tsx` : 'jsx' %></code> and save to test HMR
21
+ </p>
22
+ </div>
23
+ <p class="read-the-docs">
24
+ Click on the Vite and Preact logos to learn more
25
+ </p>
26
+ </>
27
+ )
28
+ }
@@ -0,0 +1,59 @@
1
+ <%
2
+ const harnessImport = answers.installTestingLibrary
3
+ ? `import { h } from 'preact'\nimport { render, screen, fireEvent } from '@testing-library/preact'`
4
+ : `import { h, render } from 'preact'\nimport htm from 'https://esm.sh/htm'`
5
+ const renderCommand = answers.installTestingLibrary
6
+ ? `render(<ExampleComponent />)`
7
+ : "render(html`<${ExampleComponent} />`, container)"
8
+ %>
9
+ import { expect, $ } from '@wdio/globals'
10
+ <%- harnessImport %>
11
+ <% if (answers.installTestingLibrary) { %>
12
+ import * as matchers from '@testing-library/jest-dom/matchers'
13
+ expect.extend(matchers)
14
+ <% } else { %>
15
+ // Initialize htm with Preact
16
+ const html = htm.bind(h);
17
+ <% } %>
18
+ import ExampleComponent from './Component'
19
+
20
+ describe('Preact Component Tests', () => {
21
+ <% if (answers.installTestingLibrary) { %>
22
+ it('should test component with Testing Library', async () => {
23
+ render(<ExampleComponent />)
24
+ const component = screen.getByText(/count is 0/i)
25
+ expect(component).toBeInTheDocument()
26
+
27
+ await fireEvent.click(component)
28
+ await fireEvent.click(component)
29
+
30
+ expect(screen.getByText(/count is 2/i)).toBeInTheDocument()
31
+ })
32
+ <% } else { %>
33
+ let container<%- answers.isUsingTypeScript ? `: Element` : '' %>
34
+
35
+ beforeEach(() => {
36
+ container = document.createElement('div')
37
+ document.body.appendChild(container)
38
+ })
39
+
40
+ afterEach(() => {
41
+ container?.remove()
42
+ })
43
+ <% } %>
44
+
45
+ it('should test component with WebdriverIO', async () => {
46
+ <%- renderCommand %>
47
+
48
+ const component = await $('button*=count is')
49
+ await expect(component).toBePresent()
50
+ await expect(component).toHaveText('count is 0')
51
+
52
+ await component.click()
53
+ await component.click()
54
+
55
+ await expect(component).toHaveText('count is 2')<%-
56
+ answers.includeVisualTesting ? `
57
+ await expect(component).toMatchElementSnapshot('counterButton')` : '' %>
58
+ })
59
+ })
@@ -0,0 +1,29 @@
1
+ import { useState } from 'react'
2
+
3
+ import './Component.css'
4
+
5
+ export default function ExampleComponent () {
6
+ const [count, setCount] = useState(0)
7
+
8
+ return (
9
+ <div id="root">
10
+ <div>
11
+ <a href="https://webdriver.io/docs/component-testing" target="_blank">
12
+ <img src="https://webdriver.io/assets/images/robot-3677788dd63849c56aa5cb3f332b12d5.svg" className="logo" alt="WebdriverIO logo" />
13
+ </a>
14
+ </div>
15
+ <h1>WebdriverIO Component Testing</h1>
16
+ <div className="card">
17
+ <button onClick={() => setCount((count) => count + 1)}>
18
+ count is {count}
19
+ </button>
20
+ <p>
21
+ Edit <code>src/Component.test.<%- answers.isUsingTypeScript ? `tsx` : 'jsx' %></code> and save to test HMR
22
+ </p>
23
+ </div>
24
+ <p className="read-the-docs">
25
+ Click on the WebdriverIO logo to learn more
26
+ </p>
27
+ </div>
28
+ )
29
+ }
@@ -0,0 +1,58 @@
1
+ <%
2
+ const harnessImport = answers.installTestingLibrary
3
+ ? `import { render, screen, fireEvent } from '@testing-library/react'`
4
+ : `import { createRoot } from 'react-dom/client'`
5
+ const renderCommand = answers.installTestingLibrary
6
+ ? `render(<ExampleComponent />)`
7
+ : `const root = createRoot(container)
8
+ root.render(<ExampleComponent />)`
9
+ %>
10
+ import React from 'react'
11
+ import { expect, $ } from '@wdio/globals'
12
+ <%- harnessImport %>
13
+ <% if (answers.installTestingLibrary) { %>
14
+ import * as matchers from '@testing-library/jest-dom/matchers'
15
+ expect.extend(matchers)
16
+ <% } %>
17
+ import ExampleComponent from './Component'
18
+
19
+ describe('React Component Tests', () => {
20
+ <% if (answers.installTestingLibrary) { %>
21
+ it('should test component with Testing Library', async () => {
22
+ render(<ExampleComponent />)
23
+ const component = screen.getByText(/count is 0/i)
24
+ expect(component).toBeInTheDocument()
25
+
26
+ await fireEvent.click(component)
27
+ await fireEvent.click(component)
28
+
29
+ expect(screen.getByText(/count is 2/i)).toBeInTheDocument()
30
+ })
31
+ <% } else { %>
32
+ let container<%- answers.isUsingTypeScript ? `: Element` : '' %>
33
+
34
+ beforeEach(() => {
35
+ container = document.createElement('div')
36
+ document.body.appendChild(container)
37
+ })
38
+
39
+ afterEach(() => {
40
+ container?.remove()
41
+ })
42
+ <% } %>
43
+
44
+ it('should test component with WebdriverIO', async () => {
45
+ <%- renderCommand %>
46
+
47
+ const component = await $('button*=count is')
48
+ await expect(component).toBePresent()
49
+ await expect(component).toHaveText('count is 0')
50
+
51
+ await component.click()
52
+ await component.click()
53
+
54
+ await expect(component).toHaveText('count is 2')<%-
55
+ answers.includeVisualTesting ? `
56
+ await expect(component).toMatchElementSnapshot('counterButton')` : '' %>
57
+ })
58
+ })
@@ -0,0 +1,28 @@
1
+ import { createSignal } from 'solid-js'
2
+ import './Component.css'
3
+
4
+ export default function ExampleComponent () {
5
+ const [count, setCount] = createSignal(0)
6
+
7
+ return (
8
+ <>
9
+ <div>
10
+ <a href="https://webdriver.io/docs/component-testing" target="_blank">
11
+ <img src="https://webdriver.io/assets/images/robot-3677788dd63849c56aa5cb3f332b12d5.svg" className="logo" alt="WebdriverIO logo" />
12
+ </a>
13
+ </div>
14
+ <h1>WebdriverIO Component Testing</h1>
15
+ <div class="card">
16
+ <button onClick={() => setCount((count) => count + 1)}>
17
+ count is {count}
18
+ </button>
19
+ <p>
20
+ Edit <code>src/Component.test.<%- answers.isUsingTypeScript ? `tsx` : 'jsx' %></code> and save to test HMR
21
+ </p>
22
+ </div>
23
+ <p class="read-the-docs">
24
+ Click on the Vite and Preact logos to learn more
25
+ </p>
26
+ </>
27
+ )
28
+ }
@@ -0,0 +1,58 @@
1
+ <%
2
+ const harnessImport = answers.installTestingLibrary
3
+ ? `import { cleanup, render, screen, fireEvent } from 'solid-testing-library'`
4
+ : `import { render } from 'solid-js/web'`
5
+ const renderCommand = answers.installTestingLibrary
6
+ ? `render(() => <ExampleComponent />)`
7
+ : `render(<ExampleComponent />, container)`
8
+ %>
9
+ import { expect, $ } from '@wdio/globals'
10
+ <%- harnessImport %>
11
+ <% if (answers.installTestingLibrary) { %>
12
+ import * as matchers from '@testing-library/jest-dom/matchers'
13
+ expect.extend(matchers)
14
+ <% } %>
15
+ import ExampleComponent from './Component'
16
+
17
+ describe('Preact Component Tests', () => {
18
+ <% if (answers.installTestingLibrary) { %>
19
+ afterEach(cleanup)
20
+
21
+ it('should test component with Testing Library', async () => {
22
+ render(() => <ExampleComponent />)
23
+ const component = screen.getByText(/count is 0/i)
24
+ expect(component).toBeInTheDocument()
25
+
26
+ await fireEvent.click(component)
27
+ await fireEvent.click(component)
28
+
29
+ expect(screen.getByText(/count is 2/i)).toBeInTheDocument()
30
+ })
31
+ <% } else { %>
32
+ let container<%- answers.isUsingTypeScript ? `: Element` : '' %>
33
+
34
+ beforeEach(() => {
35
+ container = document.createElement('div')
36
+ document.body.appendChild(container)
37
+ })
38
+
39
+ afterEach(() => {
40
+ container?.remove()
41
+ })
42
+ <% } %>
43
+
44
+ it('should test component with WebdriverIO', async () => {
45
+ <%- renderCommand %>
46
+
47
+ const component = await $('button*=count is')
48
+ await expect(component).toBePresent()
49
+ await expect(component).toHaveText('count is 0')
50
+
51
+ await component.click()
52
+ await component.click()
53
+
54
+ await expect(component).toHaveText('count is 2')<%-
55
+ answers.includeVisualTesting ? `
56
+ await expect(component).toMatchElementSnapshot('counterButton')` : '' %>
57
+ })
58
+ })
@@ -0,0 +1,43 @@
1
+ import { Component, Prop, h, Fragment } from '@stencil/core'
2
+
3
+ @Component({
4
+ tag: 'my-element',
5
+ shadow: true,
6
+ styleUrl: 'Component.css'
7
+ })
8
+ export class MyElement {
9
+ @Prop() count = 0
10
+ @Prop() docsHint = 'Click on the WebdriverIO logo to learn more!'
11
+
12
+ normalize(name: string): string {
13
+ if (name) {
14
+ return name.slice(0, 1).toUpperCase() + name.slice(1).toLowerCase()
15
+ }
16
+ return ''
17
+ }
18
+
19
+ render() {
20
+ return (
21
+ <>
22
+ <div>
23
+ <a href="https://webdriver.io/docs/component-testing" target="_blank">
24
+ <img src="https://webdriver.io/assets/images/robot-3677788dd63849c56aa5cb3f332b12d5.svg" class="logo"
25
+ alt="WebdriverIO logo" />
26
+ </a>
27
+ </div>
28
+ <h1>
29
+ <slot />
30
+ </h1>
31
+ <div class="card">
32
+ <button onClick={() => { this.count = this.count + 1; }} part="button">
33
+ count is {this.count}
34
+ </button>
35
+ <p>
36
+ Edit <code>src/Component.test.tsx</code> and save to test HMR
37
+ </p>
38
+ </div>
39
+ <p class="read-the-docs">{this.docsHint}</p>
40
+ </>
41
+ )
42
+ }
43
+ }
@@ -0,0 +1,45 @@
1
+ import { h } from '@stencil/core'
2
+ import { render } from '@wdio/browser-runner/stencil'
3
+ import { $, expect } from '@wdio/globals'
4
+
5
+ import { MyElement } from './Component.js'
6
+
7
+ describe('Stencil component testing', () => {
8
+ it('should increment value on click automatically', async () => {
9
+ await render({
10
+ components: [MyElement],
11
+ autoApplyChanges: true,
12
+ template: () => (
13
+ <my-element count={42}>WebdriverIO Component Testing</my-element>
14
+ )
15
+ })
16
+
17
+ const button = await $('my-element').$('button')
18
+ await expect(button).toHaveText('count is 42')
19
+
20
+ await button.click()
21
+ await button.click()
22
+
23
+ await expect(button).toHaveText('count is 44')
24
+ })
25
+
26
+ it('should increment value on click after flush', async () => {
27
+ const { flushAll } = await render({
28
+ components: [MyElement],
29
+ template: () => (
30
+ <my-element count={42}>WebdriverIO Component Testing</my-element>
31
+ )
32
+ })
33
+
34
+ const button = await $('my-element').$('button')
35
+ await expect(button).toHaveText('count is 42')
36
+
37
+ await button.click()
38
+ await button.click()
39
+ flushAll()
40
+
41
+ await expect(button).toHaveText('count is 44')<%-
42
+ answers.includeVisualTesting ? `
43
+ await expect(button).toMatchElementSnapshot('counterButton')` : '' %>
44
+ })
45
+ })