The URL object in the browser (in this case Chrome) compared to Node.js do not behave the same. As a result, I'm getting tests that pass when run in Node, but the behavior doesn't match in the browser.
To demonstrate, here's a simple parseURL function that tries to parse a URL from a string. If it can't parse it properly, then it instead returns a URL that equates to a Google search using the string provided.
function parseURL(query) {
const formattedQuery = query.includes('://') ? query : `http://${query}`;
try {
return new URL(formattedQuery);
} catch (err) {
return new URL(`https://www.google.com/search?q=${encodeURIComponent(query)}`);
}
}
And a simple Jest test to demonstrate how this function is expected to work:
describe('parseURL', () => {
it('accepts valid URL string', () => {
expect(parseURL('https://example.com')).toEqual(
new URL('https://example.com')
);
});
it('prepends protocol when missing', () => {
expect(parseURL('example.com')).toEqual(
new URL('http://example.com')
);
});
it('converts search queries', () => {
expect(parseURL('example.com lol jk')).toEqual(
new URL('https://www.google.com/search?q=example.com+lol+jk')
);
});
});
The first two tests have matching behavior for both Node.js and the browser. Great!
The third test, however, passes in Node.js even though the behavior doesn't match inside the browser. Specifically, when calling new URL('http://example.com lol jk') in Node.js, an error is raised. In the browser though, no error is raised, and instead a URL object is returned:
{
href: "http://example.com%20lol%20jk/",
origin: "http://example.com%20lol%20jk",
protocol: "http:",
username: "",
password: "",
hash: "",
host: "example.com%20lol%20jk",
hostname: "example.com%20lol%20jk",
href: "http://example.com%20lol%20jk/",
origin: "http://example.com%20lol%20jk",
password: "",
pathname: "/",
port: "",
protocol: "http:",
search: "",
searchParams: URLSearchParams {},
username: ""
}
How can I be confident that my tests reflect what is actually happening in the browser when using objects like this?