Skip to content

Commit

Permalink
attempt to figure out why test is hanging on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
ebebbington committed Apr 28, 2024
1 parent f24e1ef commit 677db67
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 139 deletions.
18 changes: 10 additions & 8 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Protocol as ProtocolClass } from "./protocol.ts";
import { Protocol as ProtocolTypes, deferred } from "../deps.ts";
import { deferred, Protocol as ProtocolTypes } from "../deps.ts";
import { Page } from "./page.ts";
import type { Browsers } from "./types.ts";
import { existsSync } from "./utility.ts";
Expand Down Expand Up @@ -178,12 +178,14 @@ export class Client {
}

// Collect all promises we need to wait for due to the browser and any page websockets
// Only needed for windows...
const pList = this.#pages.map((_page) => deferred());
pList.push(deferred());
this.#pages.forEach((page, i) => {
page.socket.onclose = () => pList[i].resolve();
// Only needed for windows... whereas waiting for the protocol socket to close is also
// needed if remote
const pList = this.#pages.map((page) => {
const prom = deferred();
page.socket.onclose = () => prom.resolve();
return prom;
});
pList.push(deferred());
this.#protocol.socket.onclose = () => pList.at(-1)?.resolve();

// Close browser process (also closes the ws endpoint, which in turn closes all sockets)
Expand All @@ -196,8 +198,8 @@ export class Client {
// When Working with Remote Browsers, where we don't control the Browser Process explicitly
await this.#protocol.send("Browser.close");
}
await Promise.all(pList)

await Promise.all(pList);

// Zombie processes is a thing with Windows, the firefox process on windows
// will not actually be closed using the above.
Expand Down
266 changes: 135 additions & 131 deletions tests/unit/client_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ for (const browserItem of browserList) {
Deno.test(`${browserItem.name}`, async (t) => {
await t.step("create()", async (t) => {
await t.step(
"Will start ${browserItem.name} headless as a subprocess",
"Uses the port when passed in to the parameters",
async () => {
const { browser } = await buildFor(browserItem.name, { remote });
const res = await fetch("http://localhost:9292/json/list");
const { browser } = await buildFor(browserItem.name, {
debuggerPort: 9999,
});
const res = await fetch("http://localhost:9999/json/list");
const json = await res.json();
// Our ws client should be able to connect if the browser is running
const client = new WebSocket(json[0]["webSocketDebuggerUrl"]);
Expand All @@ -22,18 +24,19 @@ for (const browserItem of browserList) {
client.onclose = function () {
promise.resolve();
};
console.log(1);
await promise;
console.log("awaited prom");
await browser.close();
console.log("awaited close");
},
);

await t.step(
"Uses the port when passed in to the parameters",
`Will start headless as a subprocess`,
async () => {
const { browser } = await buildFor(browserItem.name, {
debuggerPort: 9999,
});
const res = await fetch("http://localhost:9999/json/list");
const { browser } = await buildFor(browserItem.name, { remote });
const res = await fetch("http://localhost:9292/json/list");
const json = await res.json();
// Our ws client should be able to connect if the browser is running
const client = new WebSocket(json[0]["webSocketDebuggerUrl"]);
Expand All @@ -46,139 +49,140 @@ for (const browserItem of browserList) {
};
await promise;
await browser.close();
console.log("donehere too");
},
);

await t.step(
"Uses the hostname when passed in to the parameters",
async () => {
// Unable to test properly, as windows doesnt like 0.0.0.0 or localhost, so the only choice is 127.0.0.1 but this is already the default
},
);
// await t.step(
// "Uses the hostname when passed in to the parameters",
// async () => {
// // Unable to test properly, as windows doesnt like 0.0.0.0 or localhost, so the only choice is 127.0.0.1 but this is already the default
// },
// );

await t.step(
{
name: "Uses the binaryPath when passed in to the parameters",
fn: async () => {
const { browser } = await buildFor(browserItem.name, {
//binaryPath: await browserItem.getPath(),
});
// await t.step(
// {
// name: "Uses the binaryPath when passed in to the parameters",
// fn: async () => {
// const { browser } = await buildFor(browserItem.name, {
// //binaryPath: await browserItem.getPath(),
// });

const res = await fetch("http://localhost:9292/json/list");
const json = await res.json();
// Our ws client should be able to connect if the browser is running
const client = new WebSocket(json[0]["webSocketDebuggerUrl"]);
const promise = deferred();
client.onopen = function () {
client.close();
};
client.onclose = function () {
promise.resolve();
};
await promise;
await browser.close();
},
ignore: remote, //Ignoring as binary path is not a necessisty to test for remote browsers
},
);
// const res = await fetch("http://localhost:9292/json/list");
// const json = await res.json();
// // Our ws client should be able to connect if the browser is running
// const client = new WebSocket(json[0]["webSocketDebuggerUrl"]);
// const promise = deferred();
// client.onopen = function () {
// client.close();
// };
// client.onclose = function () {
// promise.resolve();
// };
// await promise;
// await browser.close();
// },
// ignore: remote, //Ignoring as binary path is not a necessisty to test for remote browsers
// },
// );
});

await t.step(`close()`, async (t) => {
await t.step(`Should close all resources and not leak any`, async () => {
const { browser, page } = await buildFor(browserItem.name, { remote });
await page.location("https://drash.land");
await browser.close();
// If resources are not closed or pending ops or leaked, this test will show it when ran
});
// await t.step(`close()`, async (t) => {
// await t.step(`Should close all resources and not leak any`, async () => {
// const { browser, page } = await buildFor(browserItem.name, { remote });
// await page.location("https://drash.land");
// await browser.close();
// // If resources are not closed or pending ops or leaked, this test will show it when ran
// });

await t.step({
name: `Should close all page specific resources too`,
fn: async () => {
const { browser, page } = await buildFor(browserItem.name, {
remote,
});
await page.location("https://drash.land");
await browser.close();
if (!remote) {
try {
const listener = Deno.listen({
port: 9292,
hostname: "localhost",
});
listener.close();
} catch (e) {
if (e instanceof Deno.errors.AddrInUse) {
throw new Error(
`Seems like the subprocess is still running: ${e.message}`,
);
}
}
} else {
const { browser: br2, page: pg2 } = await buildFor("chrome", {
remote,
});
await br2.close();
assertNotEquals(pg2.socket.url, page.socket.url);
}
// If resources are not closed or pending ops or leaked, this test will show it when ran
},
});
});
// await t.step({
// name: `Should close all page specific resources too`,
// fn: async () => {
// const { browser, page } = await buildFor(browserItem.name, {
// remote,
// });
// await page.location("https://drash.land");
// await browser.close();
// if (!remote) {
// try {
// const listener = Deno.listen({
// port: 9292,
// hostname: "localhost",
// });
// listener.close();
// } catch (e) {
// if (e instanceof Deno.errors.AddrInUse) {
// throw new Error(
// `Seems like the subprocess is still running: ${e.message}`,
// );
// }
// }
// } else {
// const { browser: br2, page: pg2 } = await buildFor("chrome", {
// remote,
// });
// await br2.close();
// assertNotEquals(pg2.socket.url, page.socket.url);
// }
// // If resources are not closed or pending ops or leaked, this test will show it when ran
// },
// });
// });

await t.step("closeAllPagesExcept()", async (t) => {
if (browserItem.name === "chrome") {
await t.step(
`Should close all pages except the one passed in`,
async () => {
const { browser, page } = await buildFor(browserItem.name, {
remote,
});
await page.location("https://drash.land");
const elem = await page.querySelector("a");
await elem.click({
button: "middle",
});
const page2 = await browser.page(2);
await browser.closeAllPagesExcept(page2);
let errMsg = "";
try {
await page.location();
} catch (e) {
errMsg = e.message;
}
const page2location = await page2.location();
await browser.close();
assertEquals(errMsg, "readyState not OPEN");
assertEquals(page2location, "https://github.com/drashland");
},
);
}
});
// await t.step("closeAllPagesExcept()", async (t) => {
// if (browserItem.name === "chrome") {
// await t.step(
// `Should close all pages except the one passed in`,
// async () => {
// const { browser, page } = await buildFor(browserItem.name, {
// remote,
// });
// await page.location("https://drash.land");
// const elem = await page.querySelector("a");
// await elem.click({
// button: "middle",
// });
// const page2 = await browser.page(2);
// await browser.closeAllPagesExcept(page2);
// let errMsg = "";
// try {
// await page.location();
// } catch (e) {
// errMsg = e.message;
// }
// const page2location = await page2.location();
// await browser.close();
// assertEquals(errMsg, "readyState not OPEN");
// assertEquals(page2location, "https://github.com/drashland");
// },
// );
// }
// });

await t.step("page()", async (t) => {
await t.step(`Should return the correct page`, async () => {
const { browser, page } = await buildFor(browserItem.name, { remote });
const mainPage = await browser.page(1);
await browser.close();
assertEquals(page.target_id, mainPage.target_id);
});
// await t.step("page()", async (t) => {
// await t.step(`Should return the correct page`, async () => {
// const { browser, page } = await buildFor(browserItem.name, { remote });
// const mainPage = await browser.page(1);
// await browser.close();
// assertEquals(page.target_id, mainPage.target_id);
// });

await t.step(
`Should throw out of bounds if index doesnt exist`,
async () => {
const { browser } = await buildFor(browserItem.name, { remote });
let threw = false;
try {
await browser.page(2);
} catch (_e) {
// As expected :)
threw = true;
} finally {
await browser.close();
assertEquals(threw, true);
}
},
);
});
// await t.step(
// `Should throw out of bounds if index doesnt exist`,
// async () => {
// const { browser } = await buildFor(browserItem.name, { remote });
// let threw = false;
// try {
// await browser.page(2);
// } catch (_e) {
// // As expected :)
// threw = true;
// } finally {
// await browser.close();
// assertEquals(threw, true);
// }
// },
// );
// });
});
}

0 comments on commit 677db67

Please sign in to comment.