Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/client/lib/FrozenTab.ts
1028 views
1
import * as Util from 'util';
2
import inspectInstanceProperties from 'awaited-dom/base/inspectInstanceProperties';
3
import StateMachine from 'awaited-dom/base/StateMachine';
4
import { IRequestInit } from 'awaited-dom/base/interfaces/official';
5
import SuperDocument from 'awaited-dom/impl/super-klasses/SuperDocument';
6
import Storage from 'awaited-dom/impl/official-klasses/Storage';
7
import Request from 'awaited-dom/impl/official-klasses/Request';
8
import Response from 'awaited-dom/impl/official-klasses/Response';
9
import { IElementIsolate, INodeIsolate } from 'awaited-dom/base/interfaces/isolate';
10
import IScreenshotOptions from '@secret-agent/interfaces/IScreenshotOptions';
11
import { INodeVisibility } from '@secret-agent/interfaces/INodeVisibility';
12
import IJsPathResult from '@secret-agent/interfaces/IJsPathResult';
13
import CoreTab from './CoreTab';
14
import Resource, { createResource } from './Resource';
15
import CookieStorage from './CookieStorage';
16
import Agent from './Agent';
17
import FrozenFrameEnvironment from './FrozenFrameEnvironment';
18
19
const { getState, setState } = StateMachine<FrozenTab, IState>();
20
21
export interface IState {
22
secretAgent: Agent;
23
coreTab: Promise<CoreTab>;
24
mainFrameEnvironment: FrozenFrameEnvironment;
25
frameEnvironments: FrozenFrameEnvironment[];
26
}
27
28
const propertyKeys: (keyof FrozenTab)[] = [
29
'lastCommandId',
30
'tabId',
31
'url',
32
'cookieStorage',
33
'localStorage',
34
'sessionStorage',
35
'document',
36
'mainFrameEnvironment',
37
'Request',
38
];
39
40
export default class FrozenTab {
41
constructor(
42
secretAgent: Agent,
43
tabAndJsPathsPromise: Promise<{ coreTab: CoreTab; prefetchedJsPaths: IJsPathResult[] }>,
44
) {
45
const mainFrameEnvironment = new FrozenFrameEnvironment(
46
secretAgent,
47
this,
48
tabAndJsPathsPromise.then(x => x.coreTab).then(x => x.mainFrameEnvironment),
49
tabAndJsPathsPromise.then(x => x.prefetchedJsPaths),
50
);
51
setState(this, {
52
secretAgent,
53
coreTab: tabAndJsPathsPromise.then(x => x.coreTab),
54
mainFrameEnvironment,
55
frameEnvironments: [mainFrameEnvironment],
56
});
57
}
58
59
public get tabId(): Promise<number> {
60
return getCoreTab(this).then(x => x.tabId);
61
}
62
63
public get lastCommandId(): Promise<number> {
64
return getCoreTab(this).then(x => x.commandQueue.lastCommandId);
65
}
66
67
public get url(): Promise<string> {
68
return this.mainFrameEnvironment.url;
69
}
70
71
public get mainFrameEnvironment(): FrozenFrameEnvironment {
72
return getState(this).mainFrameEnvironment;
73
}
74
75
public get cookieStorage(): CookieStorage {
76
return this.mainFrameEnvironment.cookieStorage;
77
}
78
79
public get document(): SuperDocument {
80
return this.mainFrameEnvironment.document;
81
}
82
83
public get localStorage(): Storage {
84
return this.mainFrameEnvironment.localStorage;
85
}
86
87
public get sessionStorage(): Storage {
88
return this.mainFrameEnvironment.sessionStorage;
89
}
90
91
public get Request(): typeof Request {
92
return this.mainFrameEnvironment.Request;
93
}
94
95
// METHODS
96
97
public async fetch(request: Request | string, init?: IRequestInit): Promise<Response> {
98
return await this.mainFrameEnvironment.fetch(request, init);
99
}
100
101
public getComputedStyle(
102
element: IElementIsolate,
103
pseudoElement?: string,
104
): ReturnType<FrozenFrameEnvironment['getComputedStyle']> {
105
return this.mainFrameEnvironment.getComputedStyle(element, pseudoElement);
106
}
107
108
public async goto(href: string, timeoutMs?: number): Promise<Resource> {
109
const coreTab = await getCoreTab(this);
110
const resource = await coreTab.goto(href, timeoutMs);
111
return createResource(Promise.resolve(coreTab), resource);
112
}
113
114
public async goBack(timeoutMs?: number): Promise<string> {
115
const coreTab = await getCoreTab(this);
116
return coreTab.goBack(timeoutMs);
117
}
118
119
public async goForward(timeoutMs?: number): Promise<string> {
120
const coreTab = await getCoreTab(this);
121
return coreTab.goForward(timeoutMs);
122
}
123
124
public async reload(timeoutMs?: number): Promise<Resource> {
125
const coreTab = await getCoreTab(this);
126
const resource = await coreTab.reload(timeoutMs);
127
return createResource(Promise.resolve(coreTab), resource);
128
}
129
130
public async getJsValue<T>(path: string): Promise<T> {
131
return await this.mainFrameEnvironment.getJsValue(path);
132
}
133
134
// @deprecated 2021-04-30: Replaced with getComputedVisibility
135
public async isElementVisible(element: IElementIsolate): Promise<boolean> {
136
return await this.getComputedVisibility(element as any).then(x => x.isVisible);
137
}
138
139
public async getComputedVisibility(node: INodeIsolate): Promise<INodeVisibility> {
140
return await this.mainFrameEnvironment.getComputedVisibility(node);
141
}
142
143
public async takeScreenshot(options?: IScreenshotOptions): Promise<Buffer> {
144
const coreTab = await getCoreTab(this);
145
return coreTab.takeScreenshot(options);
146
}
147
148
public close(): Promise<void> {
149
return getCoreTab(this).then(x => x.close());
150
}
151
152
public toJSON(): any {
153
// return empty so we can avoid infinite "stringifying" in jest
154
return {
155
type: this.constructor.name,
156
};
157
}
158
159
public [Util.inspect.custom](): any {
160
return inspectInstanceProperties(this, propertyKeys as any);
161
}
162
}
163
164
export function getCoreTab(tab: FrozenTab): Promise<CoreTab> {
165
return getState(tab).coreTab;
166
}
167
168