Skip to content

Commit 5460ec3

Browse files
authored
Add injected framework (#2122)
* Add injected framework * Remove bad using
1 parent fc40723 commit 5460ec3

File tree

7 files changed

+354
-2
lines changed

7 files changed

+354
-2
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System.Reflection.Metadata;
2+
using System.Threading.Tasks;
3+
using PuppeteerSharp.Tests.Attributes;
4+
using PuppeteerSharp.Xunit;
5+
using Xunit;
6+
using Xunit.Abstractions;
7+
8+
namespace PuppeteerSharp.Tests.InjectedTests
9+
{
10+
[Collection(TestConstants.TestFixtureCollectionName)]
11+
public class InjectedTests : PuppeteerPageBaseTest
12+
{
13+
public InjectedTests(ITestOutputHelper output) : base(output)
14+
{
15+
}
16+
17+
[PuppeteerTest("injected.spec.ts", "InjectedUtil tests", "should work")]
18+
[PuppeteerFact]
19+
public async Task ShouldWork()
20+
{
21+
var result = await (Page.MainFrame as Frame)
22+
.SecondaryWorld.EvaluateFunctionAsync<bool>(@"() => {
23+
return typeof InjectedUtil === 'object';
24+
}");
25+
Assert.True(result);
26+
}
27+
}
28+
}

lib/PuppeteerSharp.Tests/PuppeteerSharp.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<Folder Include="EmulationTests\" />
3131
<Folder Include="FixturesTests\" />
3232
<Folder Include="HeadfulTests\" />
33+
<Folder Include="InjectedTests\" />
3334
</ItemGroup>
3435
<ItemGroup>
3536
<ProjectReference Include="..\PuppeteerSharp.TestServer\PuppeteerSharp.TestServer.csproj" />
@@ -52,5 +53,6 @@
5253
<None Remove="Emulation\" />
5354
<None Remove="FixturesTests\" />
5455
<None Remove="HeadfulTests\" />
56+
<None Remove="InjectedTests\" />
5557
</ItemGroup>
5658
</Project>

lib/PuppeteerSharp/Frame.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ internal void UpdateClient(CDPSession client)
296296
Client,
297297
FrameManager,
298298
this,
299-
FrameManager.TimeoutSettings);
299+
FrameManager.TimeoutSettings,
300+
true);
300301
}
301302
}
302303
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Injected
2+
3+
This folder contains the same script that puppetter builds when it releases a new version.
4+
It's not the responsibility of this library to build the injected.js file.
5+
We just need to grab it from upstream.
6+
7+
TODO: Do this automatically :)
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
"use strict";
2+
var __defProp = Object.defineProperty;
3+
var __export = (target, all) => {
4+
for (var name in all)
5+
__defProp(target, name, { get: all[name], enumerable: true });
6+
};
7+
var __accessCheck = (obj, member, msg) => {
8+
if (!member.has(obj))
9+
throw TypeError("Cannot " + msg);
10+
};
11+
var __privateGet = (obj, member, getter) => {
12+
__accessCheck(obj, member, "read from private field");
13+
return getter ? getter.call(obj) : member.get(obj);
14+
};
15+
var __privateAdd = (obj, member, value) => {
16+
if (member.has(obj))
17+
throw TypeError("Cannot add the same private member more than once");
18+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
19+
};
20+
var __privateSet = (obj, member, value, setter) => {
21+
__accessCheck(obj, member, "write to private field");
22+
setter ? setter.call(obj, value) : member.set(obj, value);
23+
return value;
24+
};
25+
26+
// src/common/Errors.ts
27+
var CustomError = class extends Error {
28+
constructor(message) {
29+
super(message);
30+
this.name = this.constructor.name;
31+
Error.captureStackTrace(this, this.constructor);
32+
}
33+
};
34+
var TimeoutError = class extends CustomError {
35+
};
36+
var ProtocolError = class extends CustomError {
37+
constructor() {
38+
super(...arguments);
39+
this.originalMessage = "";
40+
}
41+
};
42+
var errors = Object.freeze({
43+
TimeoutError,
44+
ProtocolError
45+
});
46+
47+
// src/util/DeferredPromise.ts
48+
function createDeferredPromise(opts) {
49+
let isResolved = false;
50+
let isRejected = false;
51+
let resolver = (_) => {
52+
};
53+
let rejector = (_) => {
54+
};
55+
const taskPromise = new Promise((resolve, reject) => {
56+
resolver = resolve;
57+
rejector = reject;
58+
});
59+
const timeoutId = opts && opts.timeout > 0 ? setTimeout(() => {
60+
isRejected = true;
61+
rejector(new TimeoutError(opts.message));
62+
}, opts.timeout) : void 0;
63+
return Object.assign(taskPromise, {
64+
resolved: () => {
65+
return isResolved;
66+
},
67+
finished: () => {
68+
return isResolved || isRejected;
69+
},
70+
resolve: (value) => {
71+
if (timeoutId) {
72+
clearTimeout(timeoutId);
73+
}
74+
isResolved = true;
75+
resolver(value);
76+
},
77+
reject: (err) => {
78+
clearTimeout(timeoutId);
79+
isRejected = true;
80+
rejector(err);
81+
}
82+
});
83+
}
84+
85+
// src/injected/Poller.ts
86+
var Poller_exports = {};
87+
__export(Poller_exports, {
88+
IntervalPoller: () => IntervalPoller,
89+
MutationPoller: () => MutationPoller,
90+
RAFPoller: () => RAFPoller
91+
});
92+
93+
// src/util/assert.ts
94+
var assert = (value, message) => {
95+
if (!value) {
96+
throw new Error(message);
97+
}
98+
};
99+
100+
// src/injected/Poller.ts
101+
var _fn, _root, _observer, _promise;
102+
var MutationPoller = class {
103+
constructor(fn, root) {
104+
__privateAdd(this, _fn, void 0);
105+
__privateAdd(this, _root, void 0);
106+
__privateAdd(this, _observer, void 0);
107+
__privateAdd(this, _promise, void 0);
108+
__privateSet(this, _fn, fn);
109+
__privateSet(this, _root, root);
110+
}
111+
async start() {
112+
const promise = __privateSet(this, _promise, createDeferredPromise());
113+
const result = await __privateGet(this, _fn).call(this);
114+
if (result) {
115+
promise.resolve(result);
116+
return result;
117+
}
118+
__privateSet(this, _observer, new MutationObserver(async () => {
119+
const result2 = await __privateGet(this, _fn).call(this);
120+
if (!result2) {
121+
return;
122+
}
123+
promise.resolve(result2);
124+
await this.stop();
125+
}));
126+
__privateGet(this, _observer).observe(__privateGet(this, _root), {
127+
childList: true,
128+
subtree: true,
129+
attributes: true
130+
});
131+
return __privateGet(this, _promise);
132+
}
133+
async stop() {
134+
assert(__privateGet(this, _promise), "Polling never started.");
135+
if (!__privateGet(this, _promise).finished()) {
136+
__privateGet(this, _promise).reject(new Error("Polling stopped"));
137+
}
138+
if (__privateGet(this, _observer)) {
139+
__privateGet(this, _observer).disconnect();
140+
}
141+
}
142+
result() {
143+
assert(__privateGet(this, _promise), "Polling never started.");
144+
return __privateGet(this, _promise);
145+
}
146+
};
147+
_fn = new WeakMap();
148+
_root = new WeakMap();
149+
_observer = new WeakMap();
150+
_promise = new WeakMap();
151+
var _fn2, _promise2;
152+
var RAFPoller = class {
153+
constructor(fn) {
154+
__privateAdd(this, _fn2, void 0);
155+
__privateAdd(this, _promise2, void 0);
156+
__privateSet(this, _fn2, fn);
157+
}
158+
async start() {
159+
const promise = __privateSet(this, _promise2, createDeferredPromise());
160+
const result = await __privateGet(this, _fn2).call(this);
161+
if (result) {
162+
promise.resolve(result);
163+
return result;
164+
}
165+
const poll = async () => {
166+
if (promise.finished()) {
167+
return;
168+
}
169+
const result2 = await __privateGet(this, _fn2).call(this);
170+
if (!result2) {
171+
window.requestAnimationFrame(poll);
172+
return;
173+
}
174+
promise.resolve(result2);
175+
await this.stop();
176+
};
177+
window.requestAnimationFrame(poll);
178+
return __privateGet(this, _promise2);
179+
}
180+
async stop() {
181+
assert(__privateGet(this, _promise2), "Polling never started.");
182+
if (!__privateGet(this, _promise2).finished()) {
183+
__privateGet(this, _promise2).reject(new Error("Polling stopped"));
184+
}
185+
}
186+
result() {
187+
assert(__privateGet(this, _promise2), "Polling never started.");
188+
return __privateGet(this, _promise2);
189+
}
190+
};
191+
_fn2 = new WeakMap();
192+
_promise2 = new WeakMap();
193+
var _fn3, _ms, _interval, _promise3;
194+
var IntervalPoller = class {
195+
constructor(fn, ms) {
196+
__privateAdd(this, _fn3, void 0);
197+
__privateAdd(this, _ms, void 0);
198+
__privateAdd(this, _interval, void 0);
199+
__privateAdd(this, _promise3, void 0);
200+
__privateSet(this, _fn3, fn);
201+
__privateSet(this, _ms, ms);
202+
}
203+
async start() {
204+
const promise = __privateSet(this, _promise3, createDeferredPromise());
205+
const result = await __privateGet(this, _fn3).call(this);
206+
if (result) {
207+
promise.resolve(result);
208+
return result;
209+
}
210+
__privateSet(this, _interval, setInterval(async () => {
211+
const result2 = await __privateGet(this, _fn3).call(this);
212+
if (!result2) {
213+
return;
214+
}
215+
promise.resolve(result2);
216+
await this.stop();
217+
}, __privateGet(this, _ms)));
218+
return __privateGet(this, _promise3);
219+
}
220+
async stop() {
221+
assert(__privateGet(this, _promise3), "Polling never started.");
222+
if (!__privateGet(this, _promise3).finished()) {
223+
__privateGet(this, _promise3).reject(new Error("Polling stopped"));
224+
}
225+
if (__privateGet(this, _interval)) {
226+
clearInterval(__privateGet(this, _interval));
227+
}
228+
}
229+
result() {
230+
assert(__privateGet(this, _promise3), "Polling never started.");
231+
return __privateGet(this, _promise3);
232+
}
233+
};
234+
_fn3 = new WeakMap();
235+
_ms = new WeakMap();
236+
_interval = new WeakMap();
237+
_promise3 = new WeakMap();
238+
239+
// src/injected/util.ts
240+
var util_exports = {};
241+
__export(util_exports, {
242+
createFunction: () => createFunction
243+
});
244+
var createdFunctions = /* @__PURE__ */ new Map();
245+
var createFunction = (functionValue) => {
246+
let fn = createdFunctions.get(functionValue);
247+
if (fn) {
248+
return fn;
249+
}
250+
fn = new Function(`return ${functionValue}`)();
251+
createdFunctions.set(functionValue, fn);
252+
return fn;
253+
};
254+
255+
// src/injected/injected.ts
256+
Object.assign(
257+
self,
258+
Object.freeze({
259+
InjectedUtil: {
260+
...Poller_exports,
261+
...util_exports,
262+
createDeferredPromise
263+
}
264+
})
265+
);

0 commit comments

Comments
 (0)