Skip to content

Commit ba021e6

Browse files
authored
test: Enhanced Jasmine & Jest playground for better types testing (#2114)
* Jasmine test update with type and asymmetric matcher limitations * Use a standalone jest playground to test jest's augmentation properly * fix any * Fix Greptile comments
1 parent 26f9ec7 commit ba021e6

41 files changed

Lines changed: 7645 additions & 3436 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

playgrounds/jasmine/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Jasmine Playground
2+
3+
This is a playground for E2E testing with the `@wdio/jasmine-framework` to ensure compatibility with `expect-webdriverio`.
4+
5+
## Features and Limitations
6+
7+
* **Soft Assertions**: `SoftAssertionService` is not supported, as Jasmine provides similar behavior natively.
8+
* **Snapshots**: Basic snapshot testing currently does not work well.
9+
* **Visual Snapshots**: The `@wdio/visual-service` does not work properly due to a lack of compatible hooks in Jasmine.
10+
* **Options Configuration**: Global configurations (like `setOptions({ wait: 500 })`) are fully supported.
11+
* **Asymmetric Matchers**: Native Jasmine asymmetric matchers (like `jasmine.any()`) are not properly supported (coming soon).
12+
13+
## Test Structure
14+
15+
* `test/specs/expect-wdioImport/`: Tests using the direct import of `expect-webdriverio` (Jest-based).
16+
* `test/specs/globalImport/`: Tests using the global import, which pulls the Jasmine `expect` by default.

playgrounds/jasmine/eslint.config.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import tsEslintPlugin from '@typescript-eslint/eslint-plugin';
22
import tsParser from '@typescript-eslint/parser';
3+
import jasminePlugin from 'eslint-plugin-jasmine';
34

45
export default {
56
files: ['**/*.ts', '**/*.js'],
@@ -20,9 +21,11 @@ export default {
2021
},
2122
plugins: {
2223
'@typescript-eslint': tsEslintPlugin,
24+
'jasmine': jasminePlugin,
2325
},
2426
rules: {
2527
...tsEslintPlugin.configs['recommended'].rules,
2628
'@typescript-eslint/no-floating-promises': 'error',
29+
'jasmine/no-focused-tests': 'error',
2730
},
2831
};

playgrounds/jasmine/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"devDependencies": {
1313
"@types/jasmine": "^5.1.15",
1414
"@wdio/jasmine-framework": "^9.27.2",
15+
"eslint-plugin-jasmine": "^4.2.2",
1516
"expect-webdriverio": "file:../.."
1617
},
1718
"peerDependencies": {

playgrounds/jasmine/test/specs/basic-matchers.test.ts

Lines changed: 0 additions & 101 deletions
This file was deleted.
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import { browser, $, $$ } from '@wdio/globals'
2+
import { expect } from 'expect-webdriverio'
3+
4+
describe('Basic Expect Matchers available when pulling expect from expect-webdriverio directly', () => {
5+
beforeEach(async () => {
6+
await browser.url('https://webdriver.io')
7+
})
8+
9+
describe('Boolean matchers', () => {
10+
it('should verify truthy values', async () => {
11+
const element = await $('.navbar')
12+
const isDisplayed = await element.isDisplayed()
13+
14+
await expect(isDisplayed).toBe(true)
15+
await expect(isDisplayed).toBeTruthy()
16+
})
17+
18+
it('should verify falsy values', async () => {
19+
const element = await $('.non-existent-element')
20+
const exists = await element.isExisting()
21+
22+
await expect(exists).toBe(false)
23+
await expect(exists).toBeFalsy()
24+
})
25+
})
26+
27+
describe('String matchers', () => {
28+
it('should match exact text', async () => {
29+
const title = await browser.getTitle()
30+
await expect(title).toContain('WebdriverIO')
31+
})
32+
33+
it('should match with regex', async () => {
34+
const url = await browser.getUrl()
35+
await expect(url).toMatch(/^https:\/\/webdriver\.io/)
36+
})
37+
})
38+
39+
describe('Number matchers', () => {
40+
it('should compare numbers', async () => {
41+
const navLinks = await $$('nav a')
42+
const count = navLinks.length
43+
44+
await expect(count).toBeGreaterThan(5)
45+
await expect(count).toBeGreaterThanOrEqual(6)
46+
await expect(count).toBeLessThan(100)
47+
await expect(count).toBeLessThanOrEqual(50)
48+
})
49+
})
50+
51+
describe('Negation', () => {
52+
it('should work with not', async () => {
53+
const title = await browser.getTitle()
54+
55+
await expect(title).not.toBe('')
56+
await expect(title).not.toContain('Firefox')
57+
})
58+
})
59+
60+
61+
describe('Array matchers', () => {
62+
it('should verify array contents', async () => {
63+
const navLinks = await $$('nav a')
64+
const hrefs: string[] = []
65+
for (const link of navLinks) {
66+
const href = await link.getAttribute('href')
67+
if (href) hrefs.push(href)
68+
}
69+
70+
await expect(hrefs).toBeInstanceOf(Array)
71+
await expect(hrefs.length).toBeGreaterThan(0)
72+
await expect(hrefs).toEqual(expect.arrayContaining(['/docs/gettingstarted']))
73+
})
74+
})
75+
76+
describe('Object matchers', () => {
77+
it('should match object properties', async () => {
78+
const capabilities = await browser.capabilities
79+
80+
await expect(capabilities).toHaveProperty('browserName')
81+
await expect(capabilities).toMatchObject({
82+
browserName: 'chrome'
83+
})
84+
})
85+
})
86+
87+
describe('Async/Promise matchers', () => {
88+
it('should handle promises', async () => {
89+
const titlePromise = browser.getTitle()
90+
91+
// @ts-expect-error - to fix
92+
await expect(titlePromise).resolves.toContain('WebdriverIO')
93+
})
94+
95+
it('should not reject', async () => {
96+
const urlPromise = browser.getUrl()
97+
98+
// @ts-expect-error - to fix
99+
await expect(urlPromise).resolves.toBeDefined()
100+
})
101+
})
102+
103+
describe('Basis matcher with Jasmine asymmetric matchers', () => {
104+
it('should have toEqual work with jasmine.stringContaining', async () => {
105+
// eslint-disable-next-line -- to fix
106+
expect('title').toEqual(jasmine.stringContaining('title'))
107+
})
108+
109+
it('should have toEqual work with jasmine.any', async () => {
110+
// eslint-disable-next-line -- to fix
111+
expect('title').toEqual(jasmine.any(String))
112+
// eslint-disable-next-line -- to fix
113+
expect(123).toEqual(jasmine.any(Number))
114+
})
115+
116+
// TODO to support one day?
117+
xit('should have toEqual work with jasmine.objectContaining', async () => {
118+
// eslint-disable-next-line -- to fix
119+
expect({ a: 1, b: 2 }).toEqual(jasmine.objectContaining({ a: 1 }))
120+
})
121+
122+
// TODO to support one day?
123+
xit('should have toEqual work with jasmine.arrayContaining', async () => {
124+
// eslint-disable-next-line -- to fix
125+
expect([1, 2, 3]).toEqual(jasmine.arrayContaining([2]))
126+
})
127+
128+
it('should have toEqual work with jasmine.stringMatching', async () => {
129+
// eslint-disable-next-line -- to fix
130+
expect('title').toEqual(jasmine.stringMatching(/itl/))
131+
})
132+
133+
it('should have toEqual work with jasmine.anything', async () => {
134+
// eslint-disable-next-line -- to fix
135+
expect({ foo: 'bar' }).toEqual({ foo: jasmine.anything() })
136+
})
137+
138+
it('should have toBe not work with stringContaining', async () => {
139+
// eslint-disable-next-line -- to fix
140+
expect(() => {
141+
// eslint-disable-next-line -- to fix
142+
expect('title').toBe(jasmine.stringContaining('title'))
143+
}).toThrow()
144+
})
145+
})
146+
147+
describe('Basis matcher with asymmetric matchers', () => {
148+
it('should have toEqual work with expect.stringContaining', async () => {
149+
// eslint-disable-next-line -- to fix
150+
expect('title').toEqual(expect.stringContaining('title'))
151+
})
152+
153+
it('should have toEqual work with expect.any', async () => {
154+
// eslint-disable-next-line -- to fix
155+
expect('title').toEqual(expect.any(String))
156+
// eslint-disable-next-line -- to fix
157+
expect(123).toEqual(expect.any(Number))
158+
})
159+
160+
it('should have toEqual work with expect.objectContaining', async () => {
161+
// eslint-disable-next-line -- to fix
162+
expect({ a: 1, b: 2 }).toEqual(expect.objectContaining({ a: 1 }))
163+
})
164+
165+
it('should have toEqual work with expect.arrayContaining', async () => {
166+
// eslint-disable-next-line -- to fix
167+
expect([1, 2, 3]).toEqual(expect.arrayContaining([2]))
168+
})
169+
170+
it('should have toEqual work with expect.stringMatching', async () => {
171+
// eslint-disable-next-line -- to fix
172+
expect('title').toEqual(expect.stringMatching(/itl/))
173+
})
174+
175+
it('should have toEqual work with expect.anything', async () => {
176+
// eslint-disable-next-line -- to fix
177+
expect({ foo: 'bar' }).toEqual({ foo: expect.anything() })
178+
})
179+
180+
it('should have toEqual work with expect.closeTo', async () => {
181+
// eslint-disable-next-line -- to fix
182+
expect({ num: 1.1 }).toEqual({ num: expect.closeTo(1.101, 2) })
183+
})
184+
185+
it('should have toBe not work with stringContaining', async () => {
186+
// eslint-disable-next-line -- to fix
187+
expect(() => {
188+
// eslint-disable-next-line -- to fix
189+
expect('title').toBe(expect.stringContaining('title'))
190+
}).toThrow()
191+
})
192+
})
193+
})

playgrounds/jasmine/test/specs/wdio-matchers.test.ts renamed to playgrounds/jasmine/test/specs/expect-wdioImport/wdio-matchers.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { browser, $, $$ } from '@wdio/globals'
2+
import { expect } from 'expect-webdriverio'
23

34
describe('WebdriverIO Custom Matchers', () => {
45
beforeEach(async () => {

0 commit comments

Comments
 (0)