Closed thomaswormann closed 2 years ago
@thomaswormann can you show your whole code?
I'm trying to expose some global objects in my tests that are encapsulated in ES modules. So I'm trying to inject them through a "globals.js" file I dynamically add to the page. This file contains just "window.foo = "bar";" - so I'm expecting the console.log output to contain the string "bar".
Deno.test({
name: "FooBar",
fn: async (t) => {
const { browser, page } = await buildFor("chrome", {
defaultUrl: "about:blank",
binaryPath: Deno.env.get('DENO_CHROME_EXECUTABLE') || '/usr/bin/chromium'
});
const url = Deno.env.get('DENO_FOOBAR_URL') || 'http://localhost:8181/?locale=en_US';
await page.location(url);
const injectGlobals = await page.evaluate((window) => {
const globalsScript = document.createElement('script');
globalsScript.setAttribute("type", "module");
globalsScript.setAttribute("src", "./tests/ui/globals.js");
globalsScript.setAttribute("async", "false");
globalsScript.setAttribute("defer", "false");
document.body.appendChild(globalsScript);
return { window };
}, window);
console.log(window.foo);
}
});
@thomaswormann this won’t work, you’re still referencing the global window object in the Deno runtime and not accessing the one returned (`injectGlobals’)
You’re also passing in the window object from the Deno namespace, I think to make it work, remove the 2nd parameter in evaluate() and remove the window parameter in your callback, that way your returned value will be a reference to the page’s window object
That makes a lot of sense, I confused the global Deno "window" object with the browser one. I updated the code:
Deno.test({
// [...]
const injectGlobals = await page.evaluate(() => {
const globalsScript = document.createElement('script');
globalsScript.setAttribute("type", "module");
globalsScript.setAttribute("src", "./tests/ui/globals.js");
globalsScript.setAttribute("async", "false");
globalsScript.setAttribute("defer", "false");
document.body.appendChild(globalsScript);
return window;
});
console.log(injectGlobals.foo);
}
});
But now I get:
error: TypeError: Cannot read properties of undefined (reading 'value')
return res.result.value;
^
at Page.evaluate (https://deno.land/x/sinco@v4.1.0/src/page.ts:343:25)
I checked the document.body.innerHTML btw. and the script tag gets added, I just don't know if it gets parsed properly (I guess it should).
I wrote the res variable in page.ts:343 to the console and it says:
------- output -------
{ code: -32000, message: "Object reference chain is too long" }
----- output end -----
So maybe the window object is just to large to be passed back via the websocket connection?
It seems like it :/
There nothing we can do about that on our side i dont think, if you need the whole window, maybe return JSON.stringify(window)
, then parse JSON.parse(onjectGlobals)
? or just return the data you need:
return {
parser: window.parser,
stringHelper: window.stringHelper
}
Yes, I'll do that. Thank you for your help!
@thomaswormann let us know how it goes! feel free to re-open this issue if you still have questions/problems, maybe there is always something we can do on our end
Summary
I'm trying to get access to a global variable on the window object inside a page.evaluate() function call. I've seen the example in page.ts#L267 but I can't make it work.
I'm getting this error about a circular conversion:
I'm wondering if it's just the example being outdated or something else?