Skip to content

Commit

Permalink
chore(e2e): add bulk update E2E test (#5139)
Browse files Browse the repository at this point in the history
* add bulk update E2E test

* add a test for update favourite queries
  • Loading branch information
lerouxb authored Nov 21, 2023
1 parent ce1ef9f commit a2bd0ba
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 5 deletions.
23 changes: 18 additions & 5 deletions packages/compass-crud/src/components/bulk-update-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,16 @@ export default function BulkUpdateDialog({
}, [isOpen, wasOpen, updateText]);

return (
<Modal open={isOpen} setOpen={closeBulkUpdateDialog} size="large">
<ModalHeader title={`Update ${count || 0} documents`} subtitle={ns} />
<Modal
open={isOpen}
setOpen={closeBulkUpdateDialog}
size="large"
data-testid="bulk-update-dialog"
>
<ModalHeader
title={`Update ${count || 0} document${count === 1 ? '' : 's'}`}
subtitle={ns}
/>
<ModalBody>
<div className={columnsStyles}>
<div className={queryStyles}>
Expand Down Expand Up @@ -355,7 +363,7 @@ export default function BulkUpdateDialog({
Preview{' '}
<Description className={previewDescriptionStyles}>
(sample of {preview.changes.length} document
{preview.changes.length !== 1 && 's'})
{preview.changes.length === 1 ? '' : 's'})
</Description>
</Label>
<div className={updatePreviewStyles}>
Expand All @@ -377,15 +385,20 @@ export default function BulkUpdateDialog({
<InlineSaveQueryModal onSave={saveUpdateQuery} />
</div>
<div className={modalFooterFormActionsStyles}>
<Button variant="default" onClick={closeBulkUpdateDialog}>
<Button
variant="default"
onClick={closeBulkUpdateDialog}
data-testid="cancel-button"
>
Cancel
</Button>
<Button
disabled={!!(syntaxError || serverError)}
variant="primary"
onClick={runBulkUpdate}
data-testid="update-button"
>
Update {count} documents
Update {count} document{count === 1 ? '' : 's'}
</Button>
</div>
</ModalFooter>
Expand Down
16 changes: 16 additions & 0 deletions packages/compass-e2e-tests/helpers/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ export const ConfirmDeleteDocumentButton = `${DocumentFooter} [data-testid="dele
export const JSONDocumentCard = '[data-testid="editable-json"]';
export const JSONEditDocumentButton = `${JSONDocumentCard} [data-testid="editor-action-Edit"]`;
export const ShowMoreFieldsButton = '[data-testid="show-more-fields-button"]';
export const OpenBulkUpdateButton = '[data-testid="crud-update"]';

// Insert Document modal

Expand Down Expand Up @@ -586,6 +587,18 @@ export const importPreviewFieldHeaderCheckbox = (fieldName: string): string => {
return `[data-testid="preview-field-header-${fieldName}"] [data-testid="toggle-import-field-checkbox-${fieldName}"]`;
};

// Bulk Update Modal
export const BulkUpdateModal = '[data-testid="bulk-update-dialog"]';
export const BulkUpdateReadonlyFilter = `${BulkUpdateModal} [data-testid="readonly-filter"]`;
export const BulkUpdateUpdate = `${BulkUpdateModal} [data-testid="bulk-update-update"]`;
export const BulkUpdateTitle = `${BulkUpdateModal} [data-testid="modal-title"]`;
export const BulkUpdateUpdateButton = `${BulkUpdateModal} [data-testid="update-button"]`;
export const BulkUpdateCancelButton = `${BulkUpdateModal} [data-testid="cancel-button"]`;
export const BulkUpdatePreviewDocument = `${BulkUpdateModal} [data-testid="bulk-update-preview-document"]`;
export const BulkUpdateSaveFavorite = `${BulkUpdateModal} [data-testid="inline-save-query-modal-opener"]`;
export const BulkUpdateFavouriteNameInput = `${BulkUpdateModal} [data-testid="inline-save-query-modal-input"]`;
export const BulkUpdateFavouriteSaveButton = `${BulkUpdateModal} [data-testid="inline-save-query-modal-submit"]`;

// Connection import/export modals
export const ExportConnectionsModalOpen =
'[data-testid="favorites-menu-export-favorites-action"]';
Expand Down Expand Up @@ -669,6 +682,9 @@ export const SavedItemMenu = '[data-testid="saved-item-actions"]';
export const SavedItemMenuItemCopy = `${SavedItemMenu} [data-testid="saved-item-actions-copy-action"]`;
export const SavedItemMenuItemRename = `${SavedItemMenu} [data-testid="saved-item-actions-rename-action"]`;
export const SavedItemMenuItemDelete = `${SavedItemMenu} [data-testid="saved-item-actions-delete-action"]`;
export const FavouriteQueriesButton = `${QueryBarHistory} [data-testid="past-queries-favorites"] button`;
export const FavouriteQueryListItem = `${QueryBarHistory} [data-testid="favorite-query-list-item"]`;
export const FavouriteQueryTitle = `${QueryBarHistory} [data-testid="query-history-query-title"]`;

export const myQueriesItem = (title: string): string => {
return `[data-testid="my-queries-content"] [title="${title}"]`;
Expand Down
188 changes: 188 additions & 0 deletions packages/compass-e2e-tests/tests/collection-bulk-update.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import { expect } from 'chai';
import type { CompassBrowser } from '../helpers/compass-browser';
import { startTelemetryServer } from '../helpers/telemetry';
import type { Telemetry } from '../helpers/telemetry';
import { beforeTests, afterTests, afterTest } from '../helpers/compass';
import type { Compass } from '../helpers/compass';
import * as Selectors from '../helpers/selectors';
import { createNumbersCollection } from '../helpers/insert-data';

describe('Bulk Update', () => {
let compass: Compass;
let browser: CompassBrowser;
let telemetry: Telemetry;

before(async function () {
telemetry = await startTelemetryServer();
compass = await beforeTests({
extraSpawnArgs: ['--enableBulkUpdateOperations'],
});
browser = compass.browser;
});

after(async function () {
await afterTests(compass, this.currentTest);
await telemetry.stop();
});

beforeEach(async function () {
await createNumbersCollection();
await browser.connectWithConnectionString();
await browser.navigateToCollectionTab('test', 'numbers', 'Documents');
});

afterEach(async function () {
await afterTest(compass, this.currentTest);
});

it('updates documents matching a filter', async function () {
//const telemetryEntry = await browser.listenForTelemetryEvents(telemetry);

// Set a query that we'll use.
await browser.runFindOperation('Documents', '{ i: 5 }');

// Open the modal.
await browser.clickVisible(Selectors.OpenBulkUpdateButton);
await browser.$(Selectors.BulkUpdateModal).waitForDisplayed();

// TODO(COMPASS-7448): Make sure the query is shown in the modal.

// Check that it will update the expected number of documents
expect(await browser.$(Selectors.BulkUpdateTitle).getText()).to.equal(
'Update 1 document'
);
expect(
await browser.$(Selectors.BulkUpdateUpdateButton).getText()
).to.equal('Update 1 document');

// Check that the modal starts with the default update text
expect(
await browser.getCodemirrorEditorText(Selectors.BulkUpdateUpdate)
).to.equal('{ $set: { } }');

// Change the update text
await browser.setCodemirrorEditorValue(
Selectors.BulkUpdateUpdate,
'{ $set: { foo: "bar" } }'
);

// Wait for the preview to update accordingly
await browser.waitUntil(async () => {
const text = await browser
.$(Selectors.BulkUpdatePreviewDocument + ':first-child')
.getText();
console.log(text);
return /foo\s+:\s+"bar"/.test(text);
});

// Press update
await browser.clickVisible(Selectors.BulkUpdateUpdateButton);

// The modal should go away
await browser
.$(Selectors.BulkUpdateModal)
.waitForDisplayed({ reverse: true });

// TODO(COMPASS-7457): The toast should eventually say that it is done and have a refresh
// button, but right now it has a timeout and goes away automatically, so
// that will just flake.

// TODO(COMPASS-7388): Check the telemetry once we add it

// Keep running a new find and make sure the doc eventually matches the
// expected query (once the update ran).
// TODO(COMPASS-7457): Once we can wait for a stable toast we don't have to
// do this in a loop - we can just run this once when the update finishes.
await browser.waitUntil(async () => {
await browser.runFindOperation('Documents', '{ i: 5, foo: "bar" }');
const modifiedDocument = await browser.$(Selectors.DocumentListEntry);
await modifiedDocument.waitForDisplayed();
const doc = await getFormattedDocument(browser);
return /^_id: ObjectId\('[a-f0-9]{24}'\) i: 5 j: 0 foo: "bar"$/.test(doc);
});
});

it('can save an update query as a favourite and return to it', async function () {
// Set a query that we'll use.
await browser.runFindOperation('Documents', '{ i: { $gt: 5 } }');

// Open the modal.
await browser.clickVisible(Selectors.OpenBulkUpdateButton);
await browser.$(Selectors.BulkUpdateModal).waitForDisplayed();

// Change the update text
await browser.setCodemirrorEditorValue(
Selectors.BulkUpdateUpdate,
'{ $set: { k: 0 } }'
);

// Click save to open the popover
await browser.clickVisible(Selectors.BulkUpdateSaveFavorite);

// Fill in a name
const input = await browser.$(Selectors.BulkUpdateFavouriteNameInput);
input.waitForDisplayed();
input.setValue('My Update Query');

// Click save to save the query
await browser.$(Selectors.BulkUpdateFavouriteSaveButton).waitForEnabled();
await browser.clickVisible(Selectors.BulkUpdateFavouriteSaveButton);

// Close the modal
await browser.clickVisible(Selectors.BulkUpdateCancelButton);

// Wait for the modal to go away
await browser
.$(Selectors.BulkUpdateModal)
.waitForDisplayed({ reverse: true });

// Open the dropdown
await browser.clickVisible(Selectors.QueryBarHistoryButton);

// Wait for the popover to show
await browser.$(Selectors.QueryBarHistory).waitForDisplayed();

// Browse to Favourites
await browser.clickVisible(Selectors.FavouriteQueriesButton);

// Wait for the favourite to show and click it
await browser.waitUntil(async () => {
const favouriteElements = await browser.$$(
Selectors.FavouriteQueryListItem
);
for (const element of favouriteElements) {
const favouriteName = await element
.$(Selectors.FavouriteQueryTitle)
.getText();
console.log(favouriteName);
if (favouriteName === 'My Update Query') {
await element.click();
return true;
}
}
return false;
});

// The modal should open
await browser.$(Selectors.BulkUpdateModal).waitForDisplayed();

// TODO(COMPASS-7448): Make sure the query is shown in the modal.

// Check that the modal starts with the expected update text
expect(await browser.getCodemirrorEditorText(Selectors.BulkUpdateUpdate)).to
.equal(`{
$set: {
k: 0
}
}`);
});
});

async function getFormattedDocument(browser: CompassBrowser): Promise<string> {
const document = await browser.$(Selectors.DocumentListEntry);
await document.waitForDisplayed();
return (await document.getText())
.replace(/\n/g, ' ')
.replace(/\s+?:/g, ':')
.replace(/\s+/g, ' ');
}

0 comments on commit a2bd0ba

Please sign in to comment.