Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ describe('document-capture/components/acuant-capture', () => {

const button = await findByText('doc_auth.buttons.upload_picture');
expect(button.classList.contains('usa-button--outline')).to.be.true();
expect(console).to.have.loggedError(/^Error: Could not load script:/);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this not work because console is the real value and not the spy anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this not work because console is the real value and not the spy anymore?

Previously, we were letting JSDOM try to actually (virtually) load the script, and in this test scenario we were expecting that to fail, at which point JSDOM would log to the console, and we needed to allow for that to happen with loggedError.

Since we're no longer letting JSDOM load the scripts, the log no longer happens.

userEvent.click(button);
});

Expand Down
16 changes: 7 additions & 9 deletions spec/javascripts/spec_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@ chai.use(dirtyChai);
global.expect = chai.expect;

// Emulate a DOM, since many modules will assume the presence of these globals exist as a side
// effect of their import (focus-trap, classList.js, etc). A URL is provided as a prerequisite to
// managing history API (pushState, etc).
// effect of their import.
const dom = createDOM();
global.window = dom.window;
const windowGlobals = Object.fromEntries(
Object.getOwnPropertyNames(window)
.filter((key) => !(key in global))
.map((key) => [key, window[key]]),
);
Object.assign(global, windowGlobals);
global.window.fetch = () => Promise.reject(new Error('Fetch must be stubbed'));
global.window.crypto = new Crypto(); // In the future (Node >=15), use native webcrypto: https://nodejs.org/api/webcrypto.html
global.window.URL.createObjectURL = createObjectURLAsDataURL;
Expand All @@ -30,13 +35,6 @@ Object.defineProperty(global.window.Image.prototype, 'src', {
this.onload();
},
});
global.navigator = window.navigator;
global.document = window.document;
global.Document = window.Document;
global.Element = window.Element;
global.Node = window.Node;
global.getComputedStyle = window.getComputedStyle;
global.self = window;

useCleanDOM(dom);
useConsoleLogSpy();
Expand Down
19 changes: 18 additions & 1 deletion spec/javascripts/support/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export function createDOM() {
: Promise.reject(new Error('Failed to load'));
}
})(),
runScripts: 'dangerously',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that Object.getOwnPropertyNames(window) would return a different result with this assigned, and was missing many properties (e.g. window.Element). After tracking down why we needed this in the first place, I came up with the substitute implementation below, which is also similar to what we do for images.

});

// JSDOM doesn't implement `offsetParent`, which is used by some third-party libraries to detect
Expand Down Expand Up @@ -61,6 +60,24 @@ export function createDOM() {
.stub(dom.window, 'scrollTo')
.callsFake((scrollX, scrollY) => Object.assign(dom.window, { scrollX, scrollY }));

// If a script tag is added to the page, execute its callbacks as a successful or failed load,
// based on whether the `src` is `about:blank`.
new dom.window.MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node instanceof dom.window.HTMLScriptElement) {
if (node.src === 'about:blank') {
if (typeof node.onload === 'function') {
node.onload();
}
} else if (typeof node.onerror === 'function') {
node.onerror();
}
}
});
});
}).observe(dom.window.document.body, { childList: true, subtree: true });

return dom;
}

Expand Down