1
Play Right[github]
1
2
Play the right test- and user-oriented way with Playwright ;)
3
4
It is also a port of Selenide, Selene, NSelene, SelenideJS from
5
selenium webdriver world.
6
7
8
10
11
export const visible =
12
Condition.failIfNot('is visible', async (element: Element) => {
13
const handle = await element.handle();
14
const box = await handle.boundingBox();
15
return box !== null;
16
});
17
18
export const text = (expected: string | number | RegExp) =>
19
Condition.failIfNotActual(
20
`has text: ${expected}`,
21
query.text,
22
typeof expected === 'string'
23
? predicate.includes(expected)
24
: predicate.matches(expected),
25
);
26
27
export const exactText = (expected: string | number | RegExp) =>
28
Condition.failIfNotActual(
29
`has exact text: ${expected}`,
30
query.text,
31
typeof expected === 'string'
32
? predicate.equals(expected)
33
: predicate.matches(expected),
34
);
35
36
37
38
39
40
41
42
export const visible =
Condition.failIfNot('is visible', async (element: Element) => {
const handle = await element.handle();
const box = await handle.boundingBox();
return box !== null;
});
export const text = (expected: string | number | RegExp) =>
Condition.failIfNotActual(
`has text: ${expected}`,
query.text,
typeof expected === 'string'
? predicate.includes(expected)
: predicate.matches(expected),
);
export const exactText = (expected: string | number | RegExp) =>
Condition.failIfNotActual(
`has exact text: ${expected}`,
query.text,
typeof expected === 'string'
? predicate.equals(expected)
: predicate.matches(expected),
);
async for<R>(callable: Callable<T, R>): Promise<R> {
const finishTime = new Date().getTime() + this.timeout;
// make assertions stack point to failed client code, omit playright path
const syncStack = new Error().stack
.split('\n')
.slice(3)
.join('\n');
// eslint-disable-next-line no-constant-condition
while (true) {
try {
/* eslint-disable no-await-in-loop */
const entity = await callable.call(this.entity);
return entity;
} catch (reason) {
if (new Date().getTime() > finishTime) {
const error = new TimeoutError(
'\n'
+ `Timed out after ${this.timeout}ms, while waiting for:\n`
+ `${this.entity}.${callable}\n`
+ '\n'
+ `Reason: ${reason.message}\n`,
);
error.stack = syncStack;
const handledError = await this.handleFailure(error);
throw handledError;
/* eslint-enable no-await-in-loop */
}
}
}
}
const attributeWithValue = (name: string, value: string) =>
new Condition(`has attribute: ${name}=${value}`,
async (element: Element) => {
const attr = await query.attribute(name).call(element);
if (value !== attr) {
throw new Error(`actual ${name}="${attr}"`);
}
});
const attributeWithoutValue = (name: string) =>
new Condition(`has attribute: ${name}`, async (element: Element) => {
const attr = await query.attribute(name).call(element);
if (attr === null) {
throw new Error('actual: absent');
}
});
export const attribute = (name: string, value?: string) => {
if (value) {
return attributeWithValue(name, value);
}
return attributeWithoutValue(name);
};
export const text: Callable<Element, string> = {
toString: () => 'text',
call: element => element.handle().then(its => its.innerText()),
};
export function attribute(name: string): Callable<Element, string> {
return {
toString: () => `attribute ${name}`,
call: element => element.handle().then(its => its.getAttribute(name)),
};
}