-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathpreview.ts
138 lines (119 loc) · 4.2 KB
/
preview.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { userEvent } from '@testing-library/user-event'
import { page, server } from '@vitest/browser/context'
import {
getByAltTextSelector,
getByLabelSelector,
getByPlaceholderSelector,
getByRoleSelector,
getByTestIdSelector,
getByTextSelector,
getByTitleSelector,
} from 'ivya'
import { convertElementToCssSelector, ensureAwaited } from '../../utils'
import { getElementError } from '../public-utils'
import { Locator, selectorEngine } from './index'
page.extend({
getByLabelText(text, options) {
return new PreviewLocator(getByLabelSelector(text, options))
},
getByRole(role, options) {
return new PreviewLocator(getByRoleSelector(role, options))
},
getByTestId(testId) {
return new PreviewLocator(getByTestIdSelector(server.config.browser.locators.testIdAttribute, testId))
},
getByAltText(text, options) {
return new PreviewLocator(getByAltTextSelector(text, options))
},
getByPlaceholder(text, options) {
return new PreviewLocator(getByPlaceholderSelector(text, options))
},
getByText(text, options) {
return new PreviewLocator(getByTextSelector(text, options))
},
getByTitle(title, options) {
return new PreviewLocator(getByTitleSelector(title, options))
},
elementLocator(element: Element) {
return new PreviewLocator(
selectorEngine.generateSelectorSimple(element),
element,
)
},
})
class PreviewLocator extends Locator {
constructor(protected _pwSelector: string, protected _container?: Element) {
super()
}
override get selector() {
const selectors = this.elements().map(element => convertElementToCssSelector(element))
if (!selectors.length) {
throw getElementError(this._pwSelector, this._container || document.body)
}
return selectors.join(', ')
}
click(): Promise<void> {
return ensureAwaited(() => userEvent.click(this.element()))
}
dblClick(): Promise<void> {
return ensureAwaited(() => userEvent.dblClick(this.element()))
}
tripleClick(): Promise<void> {
return ensureAwaited(() => userEvent.tripleClick(this.element()))
}
hover(): Promise<void> {
return ensureAwaited(() => userEvent.hover(this.element()))
}
unhover(): Promise<void> {
return ensureAwaited(() => userEvent.unhover(this.element()))
}
async fill(text: string): Promise<void> {
await this.clear()
return ensureAwaited(() => userEvent.type(this.element(), text))
}
async upload(file: string | string[] | File | File[]): Promise<void> {
const uploadPromise = (Array.isArray(file) ? file : [file]).map(async (file) => {
if (typeof file !== 'string') {
return file
}
const { content: base64, basename, mime } = await this.triggerCommand<{
content: string
basename: string
mime: string
}>('__vitest_fileInfo', file, 'base64')
const fileInstance = fetch(`data:${mime};base64,${base64}`)
.then(r => r.blob())
.then(blob => new File([blob], basename, { type: mime }))
return fileInstance
})
const uploadFiles = await Promise.all(uploadPromise)
return ensureAwaited(() => userEvent.upload(this.element() as HTMLElement, uploadFiles))
}
selectOptions(options_: string | string[] | HTMLElement | HTMLElement[] | Locator | Locator[]): Promise<void> {
const options = (Array.isArray(options_) ? options_ : [options_]).map((option) => {
if (typeof option !== 'string' && 'element' in option) {
return option.element() as HTMLElement
}
return option
})
return ensureAwaited(() => userEvent.selectOptions(this.element(), options as string[] | HTMLElement[]))
}
async dropTo(): Promise<void> {
throw new Error('The "preview" provider doesn\'t support `dropTo` method.')
}
clear(): Promise<void> {
return ensureAwaited(() => userEvent.clear(this.element()))
}
async screenshot(): Promise<never> {
throw new Error('The "preview" provider doesn\'t support `screenshot` method.')
}
protected locator(selector: string) {
return new PreviewLocator(`${this._pwSelector} >> ${selector}`, this._container)
}
protected elementLocator(element: Element) {
return new PreviewLocator(
selectorEngine.generateSelectorSimple(element),
element,
)
}
}