From a6109dbd386ef419ca4633e70ac3d809b25bc99d Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Mon, 11 Nov 2024 14:51:32 +0100 Subject: [PATCH] Make sure Selects are opening before querying options --- .../test/ExportAnnotations-test.js | 33 ++++++++++++++++--- .../test/ImportAnnotations-test.js | 33 ++++++++++++++++--- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/sidebar/components/ShareDialog/test/ExportAnnotations-test.js b/src/sidebar/components/ShareDialog/test/ExportAnnotations-test.js index ae710457b25..d55d0ed3272 100644 --- a/src/sidebar/components/ShareDialog/test/ExportAnnotations-test.js +++ b/src/sidebar/components/ShareDialog/test/ExportAnnotations-test.js @@ -19,6 +19,7 @@ describe('ExportAnnotations', () => { let fakeCopyPlainText; let fakeCopyHTML; let wrappers; + let containers; const fakePrivateGroup = { type: 'private', @@ -27,19 +28,26 @@ describe('ExportAnnotations', () => { }; const createComponent = props => { + const newContainer = document.createElement('div'); + containers.push(newContainer); + document.body.appendChild(newContainer); + const wrapper = mount( , + { attachTo: newContainer }, ); wrappers.push(wrapper); + containers.push(newContainer); return wrapper; }; beforeEach(() => { wrappers = []; + containers = []; fakeAnnotationsExporter = { buildJSONExportContent: sinon.stub().returns({}), buildTextExportContent: sinon.stub().returns(''), @@ -96,12 +104,27 @@ describe('ExportAnnotations', () => { afterEach(() => { wrappers.forEach(w => w.unmount()); + containers.forEach(c => c.remove()); $imports.$restore(); }); const waitForSelect = (wrapper, testId) => waitForElement(wrapper, `Select[data-testid="${testId}"]`); + /** + * Wait for a `Select` to be found, then opens it and wait for the listbox to + * be found. + * @return Promise<{ select: EnzymeWrapper; listbox: EnzymeWrapper }> - + * The select and listbox wrappers + */ + async function waitForOpenSelect(wrapper, testId) { + const select = await waitForSelect(wrapper, testId); + select.find('button').simulate('click'); + const listbox = await waitForElement(wrapper, '[role="listbox"]'); + + return { select, listbox }; + } + const selectExportFormat = async (wrapper, format) => { const select = await waitForSelect(wrapper, 'export-format-select'); select.props().onChange({ value: format }); @@ -208,8 +231,8 @@ describe('ExportAnnotations', () => { const wrapper = createComponent(); - const userList = await waitForSelect(wrapper, 'user-select'); - const users = userList.find(Select.Option); + const { listbox } = await waitForOpenSelect(wrapper, 'user-select'); + const users = listbox.find(Select.Option); assert.equal(users.length, userEntries.length); for (const [i, entry] of userEntries.entries()) { @@ -247,11 +270,11 @@ describe('ExportAnnotations', () => { it('lists supported export formats', async () => { const wrapper = createComponent(); - const select = await waitForElement( + const { listbox } = await waitForOpenSelect( wrapper, - '[data-testid="export-format-select"]', + 'export-format-select', ); - const options = select.find(Select.Option); + const options = listbox.find(Select.Option); const optionText = (index, type) => options.at(index).find(`[data-testid="format-${type}"]`).text(); diff --git a/src/sidebar/components/ShareDialog/test/ImportAnnotations-test.js b/src/sidebar/components/ShareDialog/test/ImportAnnotations-test.js index 5bf9f2dbd29..613e5cc3c55 100644 --- a/src/sidebar/components/ShareDialog/test/ImportAnnotations-test.js +++ b/src/sidebar/components/ShareDialog/test/ImportAnnotations-test.js @@ -13,9 +13,11 @@ describe('ImportAnnotations', () => { let fakeReadExportFile; let fakeStore; let wrappers; + let containers; beforeEach(() => { wrappers = []; + containers = []; fakeReadExportFile = sinon.stub().rejects(new Error('Failed to read file')); @@ -43,17 +45,24 @@ describe('ImportAnnotations', () => { afterEach(() => { wrappers.forEach(w => w.unmount()); + containers.forEach(c => c.remove()); $imports.$restore(); }); function createImportAnnotations() { + const newContainer = document.createElement('div'); + containers.push(newContainer); + document.body.appendChild(newContainer); + const wrapper = mount( , + { attachTo: newContainer }, ); wrappers.push(wrapper); + containers.push(newContainer); return wrapper; } @@ -81,6 +90,20 @@ describe('ImportAnnotations', () => { return Boolean(getImportButton(wrapper).prop('disabled')); } + /** + * Wait for a `Select` to be found, then opens it and wait for the listbox to + * be found. + * @return Promise<{ select: EnzymeWrapper; listbox: EnzymeWrapper }> - + * The select and listbox wrappers + */ + async function waitForOpenSelect(wrapper) { + const select = await waitForElement(wrapper, Select); + select.find('button').simulate('click'); + const listbox = await waitForElement(wrapper, '[role="listbox"]'); + + return { select, listbox }; + } + it('shows a notice if the user is not logged in', () => { fakeStore.profile.returns({ userid: null }); const wrapper = createImportAnnotations(); @@ -200,8 +223,8 @@ describe('ImportAnnotations', () => { selectFile(wrapper, annotations); - const userList = await waitForElement(wrapper, Select); - const users = userList.find(Select.Option); + const { listbox } = await waitForOpenSelect(wrapper); + const users = listbox.find(Select.Option); assert.equal(users.length, userEntries.length); @@ -297,15 +320,15 @@ describe('ImportAnnotations', () => { selectFile(wrapper, annotations); - const userList = await waitForElement(wrapper, Select); - const option = userList + const { select, listbox } = await waitForOpenSelect(wrapper); + const option = listbox .find(Select.Option) .filterWhere( option => option.prop('value').userid === 'acct:brian@example.com', ) .first(); - userList.prop('onChange')(option.prop('value')); + select.prop('onChange')(option.prop('value')); wrapper.update(); const importButton = getImportButton(wrapper).getDOMNode();