-
Notifications
You must be signed in to change notification settings - Fork 170
Expand file tree
/
Copy pathview-controller.ts
More file actions
90 lines (81 loc) · 3.74 KB
/
view-controller.ts
File metadata and controls
90 lines (81 loc) · 3.74 KB
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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import * as fs from 'fs';
import { SpectronAsyncClient } from 'tests/electron/common/view-controllers/spectron-async-client';
import { DEFAULT_WAIT_FOR_ELEMENT_TO_BE_VISIBLE_TIMEOUT_MS } from 'tests/electron/setup/timeouts';
import { screenshotOnError } from '../../../end-to-end/common/screenshot-on-error';
export abstract class ViewController {
constructor(public client: SpectronAsyncClient) {}
public async waitForSelector(
selector: string,
timeout: number = DEFAULT_WAIT_FOR_ELEMENT_TO_BE_VISIBLE_TIMEOUT_MS,
): Promise<void> {
// Note: we're intentionally not using waitForVisible here because it has different
// semantics than Puppeteer; in particular, it requires the element be in the viewport
// but doesn't scroll the page to the element, so it's easy for it to fail in ways that
// are dependent on the test environment.
await this.screenshotOnError(async () => await this.client.waitForExist(selector, timeout));
}
public async waitForNumberOfSelectorMatches(
selector: string,
expectedNumber: number,
timeout: number = DEFAULT_WAIT_FOR_ELEMENT_TO_BE_VISIBLE_TIMEOUT_MS,
): Promise<void> {
await this.screenshotOnError(async () => {
await this.client.waitUntil(
async () => {
return (await this.client.$$(selector)).length === expectedNumber;
},
{
timeout,
timeoutMsg: `expected to find ${expectedNumber} matches for selector ${selector} within ${timeout}ms`,
},
);
});
}
// Webdriver waits the full implicit waitForTimeout before returning not-found.
// This means we need to wrap the waitForExist call with a longer timeout when
// reverse is true. See webdriverio@2082 and ai-web@3599.
public async waitForSelectorToDisappear(
selector: string,
timeout: number = DEFAULT_WAIT_FOR_ELEMENT_TO_BE_VISIBLE_TIMEOUT_MS * 2,
): Promise<void> {
await this.screenshotOnError(async () =>
this.client.waitForExist(
selector,
timeout,
true,
`was expecting element by selector ${selector} to disappear`,
),
);
}
// You should avoid using this in most cases!
//
// This should only be used for cases where the product's intended functionality involves a
// time-based delay (eg, a UI element animates in before becoming active), NOT sprinkled in
// randomly in the hopes that it improves reliability.
public async waitForMilliseconds(durationInMilliseconds: number): Promise<void> {
await this.client.pause(durationInMilliseconds);
}
public async click(selector: string): Promise<void> {
await this.screenshotOnError(async () => this.client.click(selector));
}
public async isEnabled(selector: string): Promise<boolean> {
return await this.screenshotOnError(async () => this.client.isEnabled(selector));
}
public async itemTextIncludesTarget(selector: string, target: string): Promise<boolean> {
return await this.screenshotOnError(async () => {
const itemText: string = await this.client.getText(selector);
return itemText.includes(target);
});
}
private async screenshotOnError<T>(wrappedFunction: () => Promise<T>): Promise<T> {
return await screenshotOnError(
path =>
this.client.browserWindow
.capturePage()
.then(buffer => fs.writeFileSync(path, buffer)),
wrappedFunction,
);
}
}