From d4ac9df5a4e297b6aa57b5400867128e94571467 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 15 Jul 2024 17:36:57 +0100 Subject: [PATCH] chore(e2e): Port usage of saving favourites including all of the in-use-encryption e2e tests to multiple connections COMPASS-8003 (#6021) * prettier weirdness * WIP * port in-use-encryption tests to multiple connections * remove debugging * scope some selectors * inverted check * rename disconnect to disconnectAll * move numLines * non-standard usage --- .../commands/connect-with-connection-form.ts | 11 +- .../connect-with-connection-string.ts | 22 +- .../helpers/commands/disconnect.ts | 2 +- .../helpers/commands/index.ts | 1 + .../helpers/commands/remove-connection.ts | 31 ++ .../save-connection-string-as-favorite.ts | 4 +- .../helpers/commands/save-favorite.ts | 2 +- .../helpers/commands/shell-eval.ts | 45 +- .../compass-e2e-tests/helpers/selectors.ts | 15 +- .../tests/auto-connect.test.ts | 4 +- .../tests/collection-export.test.ts | 2 +- .../tests/collection-import.test.ts | 2 +- .../tests/collection-rename.test.ts | 3 +- .../tests/connection-form.test.ts | 97 ++-- .../tests/connection.test.ts | 13 +- .../tests/in-use-encryption.test.ts | 461 +++++++++--------- .../tests/instance-sidebar.test.ts | 13 +- packages/compass-e2e-tests/tests/oidc.test.ts | 12 +- .../compass-e2e-tests/tests/read-only.test.ts | 17 +- .../tests/search-indexes.test.ts | 3 +- 20 files changed, 413 insertions(+), 347 deletions(-) create mode 100644 packages/compass-e2e-tests/helpers/commands/remove-connection.ts diff --git a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts index fc2ba18b529..7f862622192 100644 --- a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts +++ b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts @@ -1,6 +1,5 @@ import type { CompassBrowser } from '../compass-browser'; import type { ConnectFormState } from '../connect-form-state'; -import * as Selectors from '../selectors'; export async function connectWithConnectionForm( browser: CompassBrowser, @@ -8,9 +7,13 @@ export async function connectWithConnectionForm( connectionStatus: 'success' | 'failure' | 'either' = 'success', timeout?: number ): Promise { - const sidebar = await browser.$(Selectors.SidebarTitle); - if (await sidebar.isDisplayed()) { - await browser.disconnect(); + await browser.disconnectAll(); + + // If a connectionName is specified and a connection already exists with this + // name, make sure we don't add a duplicate so that tests can always address + // this new connection. + if (options.connectionName) { + await browser.removeConnection(options.connectionName); } await browser.setConnectFormState(options); diff --git a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts index 5a03de4a0d8..43f0f5225e0 100644 --- a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts +++ b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts @@ -12,7 +12,7 @@ export async function connectWithConnectionString( connectionStatus: 'success' | 'failure' | 'either' = 'success', timeout?: number ): Promise { - await browser.disconnect(); + await browser.disconnectAll(); if (TEST_MULTIPLE_CONNECTIONS) { // if the modal is still animating away when we're connecting again, things @@ -24,25 +24,7 @@ export async function connectWithConnectionString( // if a connection with this name already exists, remove it otherwise we'll // add a duplicate and things will get complicated fast const connectionName = connectionNameFromString(connectionString); - - // make sure there's no filter because if the connection is not displayed then we can't remove it - if (await browser.$(Selectors.SidebarFilterInput).isExisting()) { - await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, ''); - - // wait for a connection to appear. It must because if there are no - // connections the filter field wouldn't exist in the first place - await browser.$(Selectors.SidebarTreeItems).waitForDisplayed(); - } - - const selector = Selectors.sidebarConnection(connectionName); - if (await browser.$(selector).isExisting()) { - await browser.selectConnectionMenuItem( - connectionName, - Selectors.Multiple.RemoveConnectionItem - ); - await browser.$(selector).waitForExist({ reverse: true }); - } + await browser.removeConnection(connectionName); await browser.clickVisible(Selectors.Multiple.SidebarNewConnectionButton); await browser.$(Selectors.ConnectionModal).waitForDisplayed(); diff --git a/packages/compass-e2e-tests/helpers/commands/disconnect.ts b/packages/compass-e2e-tests/helpers/commands/disconnect.ts index 45b27a078fe..2591d85e3d5 100644 --- a/packages/compass-e2e-tests/helpers/commands/disconnect.ts +++ b/packages/compass-e2e-tests/helpers/commands/disconnect.ts @@ -7,7 +7,7 @@ import Debug from 'debug'; const debug = Debug('compass-e2e-tests'); -export async function disconnect(browser: CompassBrowser): Promise { +export async function disconnectAll(browser: CompassBrowser): Promise { if (TEST_COMPASS_WEB) { const url = new URL(await browser.getUrl()); url.pathname = '/'; diff --git a/packages/compass-e2e-tests/helpers/commands/index.ts b/packages/compass-e2e-tests/helpers/commands/index.ts index 7189e3fb559..0abd5d31fa2 100644 --- a/packages/compass-e2e-tests/helpers/commands/index.ts +++ b/packages/compass-e2e-tests/helpers/commands/index.ts @@ -67,3 +67,4 @@ export * from './drop-index'; export * from './hide-index'; export * from './unhide-index'; export * from './hide-visible-toasts'; +export * from './remove-connection'; diff --git a/packages/compass-e2e-tests/helpers/commands/remove-connection.ts b/packages/compass-e2e-tests/helpers/commands/remove-connection.ts new file mode 100644 index 00000000000..f63da9a928f --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/remove-connection.ts @@ -0,0 +1,31 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; +import type { CompassBrowser } from '../compass-browser'; +import * as Selectors from '../selectors'; + +export async function removeConnection( + browser: CompassBrowser, + connectionName: string +): Promise { + if (!TEST_MULTIPLE_CONNECTIONS) { + return; + } + + // make sure there's no filter because if the connection is not displayed then we can't remove it + if (await browser.$(Selectors.SidebarFilterInput).isExisting()) { + await browser.clickVisible(Selectors.SidebarFilterInput); + await browser.setValueVisible(Selectors.SidebarFilterInput, ''); + + // wait for a connection to appear. It must because if there are no + // connections the filter field wouldn't exist in the first place + await browser.$(Selectors.SidebarTreeItems).waitForDisplayed(); + } + + const selector = Selectors.sidebarConnection(connectionName); + if (await browser.$(selector).isExisting()) { + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.RemoveConnectionItem + ); + await browser.$(selector).waitForExist({ reverse: true }); + } +} diff --git a/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts b/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts index 6caf276b684..9130661f9fc 100644 --- a/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts +++ b/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts @@ -3,8 +3,8 @@ import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; -// TODO(COMPASS-8003,COMPASS-8023): Just remove this command and use -// setConnectionFormState() once we remove the single connection code +// TODO(COMPASS-8023): Just remove this command and use setConnectionFormState() +// once we remove the single connection code export async function saveConnectionStringAsFavorite( browser: CompassBrowser, connectionString: string, diff --git a/packages/compass-e2e-tests/helpers/commands/save-favorite.ts b/packages/compass-e2e-tests/helpers/commands/save-favorite.ts index d463347626d..e2a31a0120e 100644 --- a/packages/compass-e2e-tests/helpers/commands/save-favorite.ts +++ b/packages/compass-e2e-tests/helpers/commands/save-favorite.ts @@ -3,7 +3,7 @@ import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; import { expect } from 'chai'; -// TODO(COMPASS-8003,COMPASS-8023): Just remove this command and use +// TODO(COMPASS-8023): Just remove this command and use // setConnectionFormState() once we remove the single connection code export async function saveFavorite( browser: CompassBrowser, diff --git a/packages/compass-e2e-tests/helpers/commands/shell-eval.ts b/packages/compass-e2e-tests/helpers/commands/shell-eval.ts index 7ee0599b7b6..5ab994decd4 100644 --- a/packages/compass-e2e-tests/helpers/commands/shell-eval.ts +++ b/packages/compass-e2e-tests/helpers/commands/shell-eval.ts @@ -10,32 +10,43 @@ async function getOutputText(browser: CompassBrowser): Promise { export async function shellEval( browser: CompassBrowser, connectionName: string, - str: string, + input: string | string[], parse = false ): Promise { // Keep in mind that for multiple connections this will open a new tab and // focus it. await browser.openShell(connectionName); - const numLines = (await getOutputText(browser)).length; + const strings = Array.isArray(input) ? input : [input]; - const command = parse === true ? `JSON.stringify(${str})` : str; + for (const str of strings) { + const numLines = (await getOutputText(browser)).length; - await browser.setCodemirrorEditorValue(Selectors.ShellInputEditor, command); - await browser.keys(['Enter']); + const command = parse === true ? `JSON.stringify(${str})` : str; - // wait until more output appears - await browser.waitUntil(async () => { - const lines = await getOutputText(browser); - return ( - lines.length > - /** - * input line becomes an output line on enter press, so we are waiting - * for two new lines to appear, not just one - */ - numLines + 1 - ); - }); + await browser.setCodemirrorEditorValue(Selectors.ShellInputEditor, command); + await browser.keys(['Enter']); + + // wait until more output appears + await browser.waitUntil(async () => { + const lines = await getOutputText(browser); + if ( + lines.length > + /** + * input line becomes an output line on enter press, so we are waiting + * for two new lines to appear, not just one + */ + numLines + 1 + ) { + // make sure the prompt shows up before entering another line or continueing on + await browser + .$(`${Selectors.ShellInput} [aria-label="Chevron Right Icon"]`) + .waitForDisplayed(); + return true; + } + return false; + }); + } const output = await getOutputText(browser); diff --git a/packages/compass-e2e-tests/helpers/selectors.ts b/packages/compass-e2e-tests/helpers/selectors.ts index 98fe21b5992..a4a5f35b794 100644 --- a/packages/compass-e2e-tests/helpers/selectors.ts +++ b/packages/compass-e2e-tests/helpers/selectors.ts @@ -258,6 +258,8 @@ export const Single = { '[data-testid="favorites-menu-export-saved-connections-action"]', ImportConnectionsModalOpen: '[data-testid="favorites-menu-import-saved-connections-action"]', + + InUseEncryptionMarker: '[data-testid="fle-connection-configuration"]', }; // Multiple Connections sidebar @@ -296,6 +298,8 @@ export const Multiple = { '[data-testid="connections-list-title-actions-export-saved-connections-action"]', ImportConnectionsModalOpen: '[data-testid="connections-list-title-actions-import-saved-connections-action"]', + + InUseEncryptionMarker: '[data-action="open-csfle-modal"]', }; // Rename Collection Modal @@ -327,9 +331,6 @@ export const CreateCollectionButton = '[data-action="create-collection"]'; export const DropCollectionButton = '[data-action="drop-collection"]'; export const DatabaseCollectionPlaceholder = '[data-testid="placeholder"]'; -export const FleConnectionConfigurationBanner = - '[data-testid="fle-connection-configuration"]'; - export const sidebarDatabase = (dbName: string): string => { return `${Sidebar} [data-database-name="${dbName}"]`; }; @@ -357,6 +358,13 @@ export const sidebarConnectionButton = (connectionName: string): string => { return `${sidebarConnection(connectionName)} > div > button`; }; +export const sidebarConnectionActionButton = ( + connectionName: string, + selector: string +): string => { + return `${sidebarConnection(connectionName)} ${selector}`; +}; + export const sidebarConnectionMenuButton = (connectionName: string): string => { return `${sidebarConnection(connectionName)} button[title="Show actions"]`; }; @@ -473,6 +481,7 @@ export const ShellSection = '[data-testid="shell-section"]'; export const ShellContent = '[data-testid="shell-content"]'; export const ShellExpandButton = '[data-testid="shell-expand-button"]'; export const ShellInputEditor = '[data-testid="shell-input"] [data-codemirror]'; +export const ShellInput = '[data-testid="shell-input"]'; export const ShellOutput = '[data-testid="shell-output"]'; // Instance screen diff --git a/packages/compass-e2e-tests/tests/auto-connect.test.ts b/packages/compass-e2e-tests/tests/auto-connect.test.ts index d104680b4e2..6cbe7bba03a 100644 --- a/packages/compass-e2e-tests/tests/auto-connect.test.ts +++ b/packages/compass-e2e-tests/tests/auto-connect.test.ts @@ -218,7 +218,7 @@ describe('Automatically connecting from the command line', function () { location.reload(); }); await browser.waitForConnectionResult('success'); - await browser.disconnect(); + await browser.disconnectAll(); await browser.execute(() => { location.reload(); }); @@ -276,7 +276,7 @@ describe('Automatically connecting from the command line', function () { try { const browser = compass.browser; await browser.waitForConnectionResult('success'); - await browser.disconnect(); + await browser.disconnectAll(); // this is not the ideal check because by default the recent connections // list doesn't exist either diff --git a/packages/compass-e2e-tests/tests/collection-export.test.ts b/packages/compass-e2e-tests/tests/collection-export.test.ts index 4c2556f4b1c..244e668ddb9 100644 --- a/packages/compass-e2e-tests/tests/collection-export.test.ts +++ b/packages/compass-e2e-tests/tests/collection-export.test.ts @@ -830,7 +830,7 @@ describe('Collection export', function () { const exportAbortButton = await browser.$(Selectors.ExportToastAbort); await exportAbortButton.waitForDisplayed(); - await browser.disconnect(); + await browser.disconnectAll(); await browser .$(Selectors.SidebarTitle) .waitForDisplayed({ reverse: true }); diff --git a/packages/compass-e2e-tests/tests/collection-import.test.ts b/packages/compass-e2e-tests/tests/collection-import.test.ts index f70a3d34e2a..596868f8c7e 100644 --- a/packages/compass-e2e-tests/tests/collection-import.test.ts +++ b/packages/compass-e2e-tests/tests/collection-import.test.ts @@ -1367,7 +1367,7 @@ describe('Collection import', function () { // Wait for the in progress toast to appear. await browser.$(Selectors.ImportToastAbort).waitForDisplayed(); - await browser.disconnect(); + await browser.disconnectAll(); await browser .$(Selectors.SidebarTitle) .waitForDisplayed({ reverse: true }); diff --git a/packages/compass-e2e-tests/tests/collection-rename.test.ts b/packages/compass-e2e-tests/tests/collection-rename.test.ts index 54f22433bcb..b6271a74c31 100644 --- a/packages/compass-e2e-tests/tests/collection-rename.test.ts +++ b/packages/compass-e2e-tests/tests/collection-rename.test.ts @@ -11,7 +11,6 @@ import type { CompassBrowser } from '../helpers/compass-browser'; import { createBlankCollection, dropDatabase } from '../helpers/insert-data'; import * as Selectors from '../helpers/selectors'; -import { setFeature } from '../helpers/commands'; const initialName = 'numbers'; const newName = 'renamed'; @@ -114,7 +113,7 @@ describe('Collection Rename Modal', () => { compass = await init(this.test?.fullTitle()); browser = compass.browser; - await setFeature(browser, 'enableRenameCollectionModal', true); + await browser.setFeature('enableRenameCollectionModal', true); }); beforeEach(async function () { diff --git a/packages/compass-e2e-tests/tests/connection-form.test.ts b/packages/compass-e2e-tests/tests/connection-form.test.ts index 36a6307cc2c..1b7838e3fba 100644 --- a/packages/compass-e2e-tests/tests/connection-form.test.ts +++ b/packages/compass-e2e-tests/tests/connection-form.test.ts @@ -65,8 +65,8 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } expect(state).to.deep.equal(expectedState); @@ -99,9 +99,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -138,9 +138,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017,127.0.0.1:27091'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017,127.0.0.1:27091'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -177,9 +177,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -222,9 +222,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -267,9 +267,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } await browser.setValueVisible( @@ -340,9 +340,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -382,9 +382,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -426,9 +426,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -472,9 +472,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -519,9 +519,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -566,8 +566,8 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } expect(await browser.getConnectFormState()).to.deep.equal(expectedState); @@ -613,8 +613,8 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } expect(await browser.getConnectFormState()).to.deep.equal(expectedState); @@ -658,9 +658,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(false); @@ -785,9 +785,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -799,8 +799,10 @@ describe('Connection form', function () { ); }); - it('supports favorites', async function () { + it('supports saving a favorite (multiple connections)', async function () { if (!TEST_MULTIPLE_CONNECTIONS) { + // this will remain skipped until we remove the test because the test is + // now for the multiple connections case only this.skip(); } @@ -833,9 +835,10 @@ describe('Connection form', function () { }); }); - it('can save & connect', async function () { - // TODO(COMPASS-8003): saving a favorite is now part of the connect form + it('supports saving a favorite (single connection)', async function () { if (TEST_MULTIPLE_CONNECTIONS) { + // this will remain skipped until we remove the test because the test is + // now for the single connection case only this.skip(); } @@ -849,6 +852,8 @@ describe('Connection form', function () { // Save & Connect await browser.clickVisible(Selectors.SaveAndConnectButton); + + // Fill out the favorite info await browser.$(Selectors.FavoriteModal).waitForDisplayed(); await browser.setValueVisible(Selectors.FavoriteNameInput, favoriteName); await browser.clickVisible( @@ -876,6 +881,6 @@ describe('Connection form', function () { favoriteName ); - await browser.disconnect(); + await browser.disconnectAll(); }); }); diff --git a/packages/compass-e2e-tests/tests/connection.test.ts b/packages/compass-e2e-tests/tests/connection.test.ts index 59a93233cd3..29cdb033c17 100644 --- a/packages/compass-e2e-tests/tests/connection.test.ts +++ b/packages/compass-e2e-tests/tests/connection.test.ts @@ -23,7 +23,7 @@ import * as Selectors from '../helpers/selectors'; async function disconnect(browser: CompassBrowser) { try { - await browser.disconnect(); + await browser.disconnectAll(); } catch (err) { console.error('Error during disconnect:'); console.error(err); @@ -200,7 +200,16 @@ async function assertCannotCreateDb( } // open the create database modal from the sidebar - await browser.clickVisible(Sidebar.CreateDatabaseButton); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + connectionName, + Sidebar.CreateDatabaseButton + ) + ); + } else { + await browser.clickVisible(Sidebar.CreateDatabaseButton); + } const createModalElement = await browser.$(Selectors.CreateDatabaseModal); await createModalElement.waitForDisplayed(); diff --git a/packages/compass-e2e-tests/tests/in-use-encryption.test.ts b/packages/compass-e2e-tests/tests/in-use-encryption.test.ts index 752a8f33915..28b797be154 100644 --- a/packages/compass-e2e-tests/tests/in-use-encryption.test.ts +++ b/packages/compass-e2e-tests/tests/in-use-encryption.test.ts @@ -7,8 +7,6 @@ import { serverSatisfies, skipForWeb, TEST_MULTIPLE_CONNECTIONS, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -16,17 +14,25 @@ import { getFirstListDocument } from '../helpers/read-first-document-content'; import { MongoClient } from 'mongodb'; import delay from '../helpers/delay'; +import type { ConnectFormState } from '../helpers/connect-form-state'; const CONNECTION_HOSTS = '127.0.0.1:27091'; const CONNECTION_STRING = `mongodb://${CONNECTION_HOSTS}/`; -async function refresh(browser: CompassBrowser) { +async function refresh(browser: CompassBrowser, connectionName: string) { // We refresh immediately after running commands, so there is an opportunity // for race conditions. Ideally we'd wait for something to become true, then // hit refresh, then wait for a transition to occur that will correlate to the // data actually being refreshed and arriving. - await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.RefreshDatabasesItem + ); + } else { + await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); + } } /** @@ -43,18 +49,13 @@ async function refresh(browser: CompassBrowser) { * and never sent in plaintext. */ describe('CSFLE / QE', function () { + // reuse the same connectionName so that connectWithConnectionForm (or + // connectWithConnectionString for that matter) will remove the connection + // every time before connecting + const connectionName = 'fle'; + before(function () { skipForWeb(this, 'not available in compass-web'); - - // TODO(COMPASS-8003): This will have to be refactored for multiple - // connections because saving a favorite is now part of the connect modal - // and there is no favorite modal anymore. Many of these tests also use - // shellEval() which is better to port once we have the shell working - // properly in multiple connections and they also use a refresh - // databases&collections button that doesn't exist yet. - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } }); describe('server version gte 4.2.20 and not a linux platform', function () { @@ -77,10 +78,7 @@ describe('CSFLE / QE', function () { }); beforeEach(async function () { - const sidebar = await browser.$(Selectors.SidebarTitle); - if (await sidebar.isDisplayed()) { - await browser.disconnect(); - } + await browser.disconnectAll(); }); afterEach(async function () { @@ -96,8 +94,7 @@ describe('CSFLE / QE', function () { }); it('does not store KMS settings if the checkbox is not set', async function () { - const favoriteName = 'My FLE Favorite'; - const options = { + const options: ConnectFormState = { hosts: [CONNECTION_HOSTS], fleKeyVaultNamespace: `${databaseName}.keyvault`, fleKey: 'A'.repeat(128), @@ -115,63 +112,94 @@ describe('CSFLE / QE', function () { }`, }; - await browser.setConnectFormState(options); - // Save & Connect - await browser.clickVisible( - TEST_MULTIPLE_CONNECTIONS - ? Selectors.ConnectionModalConnectButton - : Selectors.SaveAndConnectButton - ); - await browser.$(Selectors.FavoriteModal).waitForDisplayed(); - await browser.setValueVisible(Selectors.FavoriteNameInput, favoriteName); - await browser.clickVisible( - `${Selectors.FavoriteColorSelector} [data-testid="color-pick-color2"]` - ); + if (TEST_MULTIPLE_CONNECTIONS) { + // in the multiple connections world the favorite form fields are just + // part of the connection form + options.connectionName = connectionName; + options.connectionColor = 'color1'; + options.connectionFavorite = true; + + await browser.setConnectFormState(options); + + await browser.clickVisible(Selectors.ConnectionModalConnectButton); + } else { + // in the single connections world the favorite form fields are in a + // separate modal + await browser.setConnectFormState(options); + await browser.clickVisible(Selectors.SaveAndConnectButton); + await browser.$(Selectors.FavoriteModal).waitForDisplayed(); + await browser.setValueVisible( + Selectors.FavoriteNameInput, + connectionName + ); + await browser.clickVisible( + `${Selectors.FavoriteColorSelector} [data-testid="color-pick-color2"]` + ); - // The modal's button text should read Save & Connect and not the default Save - expect(await browser.$(Selectors.FavoriteSaveButton).getText()).to.equal( - 'Save & Connect' - ); + // The modal's button text should read Save & Connect and not the default Save + expect( + await browser.$(Selectors.FavoriteSaveButton).getText() + ).to.equal('Save & Connect'); - await browser.$(Selectors.FavoriteSaveButton).waitForEnabled(); - await browser.clickVisible(Selectors.FavoriteSaveButton); - await browser.$(Selectors.FavoriteModal).waitForExist({ reverse: true }); + await browser.$(Selectors.FavoriteSaveButton).waitForEnabled(); + await browser.clickVisible(Selectors.FavoriteSaveButton); + await browser + .$(Selectors.FavoriteModal) + .waitForExist({ reverse: true }); + } // Wait for it to connect - const element = await browser.$(Selectors.MyQueriesList); - await element.waitForDisplayed(); + await browser.waitForConnectionResult('success'); + // extra pause to make very sure that it saved the connection before we disconnect await delay(10000); try { - await browser.disconnect(); + await browser.disconnectAll(); } catch (err) { console.error('Error during disconnect:'); console.error(err); } + // extra pause to make very sure that it loaded the connections await delay(10000); await browser.screenshot('saved-connections-after-disconnect.png'); - await browser.clickVisible( - Selectors.sidebarConnectionButton(favoriteName) - ); + if (TEST_MULTIPLE_CONNECTIONS) { + // in the multiple connections world, if we clicked the connection it + // would connect and that's not what we want in this case. So we select + // edit from the menu. + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.EditConnectionItem + ); + } else { + // in the single connections world, clicking the favorite connection in + // the sidebar doesn't connect, it just pre-populates the form + await browser.clickVisible( + Selectors.sidebarConnectionButton(connectionName) + ); + } + + // The modal should appear and the title of the modal should be the favorite name await browser.waitUntil(async () => { const connectionTitleSelector = TEST_MULTIPLE_CONNECTIONS ? Selectors.ConnectionModalTitle : Selectors.ConnectionTitle; const text = await browser.$(connectionTitleSelector).getText(); - return text === favoriteName; + return text === connectionName; }); + // The form should have the relevant field values const state = await browser.getConnectFormState(); - expect(state.connectionString).to.be.equal(CONNECTION_STRING); - expect(state.fleKeyVaultNamespace).to.be.equal('fle-test.keyvault'); + expect(state.fleKeyVaultNamespace).to.be.equal( + `${databaseName}.keyvault` + ); expect(state.fleStoreCredentials).to.be.equal(false); expect(state.fleEncryptedFieldsMap).to.include( - 'fle-test.my-another-collection' + `${databaseName}.${collectionName}` ); }); }); @@ -187,9 +215,9 @@ describe('CSFLE / QE', function () { describe('when fleEncryptedFieldsMap is not specified while connecting', function () { const databaseName = 'db-for-fle'; const collectionName = 'my-encrypted-collection'; - const connectionName = 'fle'; let compass: Compass; let browser: CompassBrowser; + const connectionName = 'fle'; before(async function () { compass = await init(this.test?.fullTitle()); @@ -201,11 +229,12 @@ describe('CSFLE / QE', function () { connectionName, }); + // create a collection so we can navigate to the database await browser.shellEval( connectionName, `db.getMongo().getDB('${databaseName}').createCollection('default')` ); - await refresh(browser); + await refresh(browser, connectionName); }); after(async function () { @@ -222,7 +251,7 @@ describe('CSFLE / QE', function () { it('can create a fle2 collection with encryptedFields', async function () { await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); @@ -244,7 +273,7 @@ describe('CSFLE / QE', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); @@ -282,7 +311,6 @@ describe('CSFLE / QE', function () { let compass: Compass; let browser: CompassBrowser; let plainMongo: MongoClient; - let connectionName: string; before(async function () { compass = await init(this.test?.fullTitle()); @@ -290,8 +318,6 @@ describe('CSFLE / QE', function () { }); beforeEach(async function () { - connectionName = this.test?.fullTitle() ?? ''; - await browser.connectWithConnectionForm({ hosts: [CONNECTION_HOSTS], fleKeyVaultNamespace: `${databaseName}.keyvault`, @@ -335,9 +361,8 @@ describe('CSFLE / QE', function () { }`, connectionName, }); - await browser.shellEval(connectionName, `use ${databaseName}`); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, 'db.keyvault.insertOne({' + '"_id": UUID("28bbc608-524e-4717-9246-33633361788e"),' + '"keyMaterial": BinData(0, "/yeYyj8IxowIIZGOs5iUcJaUm7KHhoBDAAzNxBz8c5mr2hwBIsBWtDiMU4nhx3fCBrrN3cqXG6jwPgR22gZDIiMZB5+xhplcE9EgNoEEBtRufBE2VjtacpXoqrMgW0+m4Dw76qWUCsF/k1KxYBJabM35KkEoD6+BI1QxU0rwRsR1rE/OLuBPKOEq6pmT5x74i+ursFlTld+5WiOySRDcZg=="),' + @@ -345,9 +370,11 @@ describe('CSFLE / QE', function () { '"updateDate": ISODate("2022-05-27T18:28:33.925Z"),' + '"status": 0,' + '"masterKey": { "provider" : "local" }' + - '})' - ); - await refresh(browser); + '})', + // make sure there is a collection so we can navigate to the database + `db.getMongo().getDB('${databaseName}').createCollection('default')`, + ]); + await refresh(browser, connectionName); plainMongo = await MongoClient.connect(CONNECTION_STRING); }); @@ -368,14 +395,14 @@ describe('CSFLE / QE', function () { it('can create a fle2 collection without encryptedFields', async function () { await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); await browser.clickVisible(Selectors.DatabaseCreateCollectionButton); await browser.addCollection(collectionName); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); @@ -415,11 +442,11 @@ describe('CSFLE / QE', function () { }); it('can insert a document with an encrypted field and a non-encrypted field', async function () { - await browser.shellEval( - connectionName, - `db.createCollection('${collectionName}')` - ); - await refresh(browser); + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( databaseName, @@ -474,17 +501,14 @@ describe('CSFLE / QE', function () { }); it('shows a decrypted field icon', async function () { - await browser.shellEval( - connectionName, - `db.createCollection('${collectionName}')` - ); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( databaseName, @@ -524,17 +548,14 @@ describe('CSFLE / QE', function () { const toString = (v: any) => v?.toISOString?.()?.replace(/Z$/, '+00:00') ?? JSON.stringify(v); - await browser.shellEval( - connectionName, - `db.createCollection('${coll}')` - ); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${coll}')`, `db[${JSON.stringify( coll - )}].insertOne({ "${field}": ${oldValue}, "name": "Person X" })` - ); - await refresh(browser); + )}].insertOne({ "${field}": ${oldValue}, "name": "Person X" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( databaseName, @@ -596,17 +617,14 @@ describe('CSFLE / QE', function () { } it('can edit and query the encrypted field in the JSON view', async function () { - await browser.shellEval( - connectionName, - `db.createCollection('${collectionName}')` - ); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( databaseName, @@ -654,17 +672,14 @@ describe('CSFLE / QE', function () { }); it('can not edit the copied encrypted field', async function () { - await browser.shellEval( - connectionName, - `db.createCollection('${collectionName}')` - ); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })`, + ]); + await refresh(browser, connectionName); const doc = await plainMongo .db(databaseName) @@ -677,7 +692,7 @@ describe('CSFLE / QE', function () { name: 'La La', }); - await refresh(browser); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( databaseName, collectionName, @@ -739,17 +754,14 @@ describe('CSFLE / QE', function () { }); it('shows incomplete schema for cloned document banner', async function () { - await browser.shellEval( - connectionName, - `db.createCollection('${collectionName}')` - ); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "First" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "First" })`, + ]); + await refresh(browser, connectionName); const doc = await plainMongo .db(databaseName) @@ -762,7 +774,7 @@ describe('CSFLE / QE', function () { name: 'Second', }); - await refresh(browser); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( databaseName, collectionName, @@ -837,17 +849,14 @@ describe('CSFLE / QE', function () { }); it('can enable and disable in-use encryption from the sidebar', async function () { - await browser.shellEval( - connectionName, - `db.createCollection('${collectionName}')` - ); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( databaseName, @@ -865,17 +874,25 @@ describe('CSFLE / QE', function () { name: '"Person Z"', }); - await browser.clickVisible(Selectors.FleConnectionConfigurationBanner); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + connectionName, + Selectors.Multiple.InUseEncryptionMarker + ) + ); + } else { + await browser.clickVisible(Selectors.Single.InUseEncryptionMarker); + } - let modal = await browser.$(Selectors.CSFLEConnectionModal); - await modal.waitForDisplayed(); + await browser.$(Selectors.CSFLEConnectionModal).waitForDisplayed(); await browser.clickVisible(Selectors.SetCSFLEEnabledLabel); - await browser.screenshot('csfle-connection-modal.png'); - await browser.clickVisible(Selectors.CSFLEConnectionModalCloseButton); - await modal.waitForDisplayed({ reverse: true }); + await browser + .$(Selectors.CSFLEConnectionModal) + .waitForDisplayed({ reverse: true }); const encryptedResult = await getFirstListDocument(browser); @@ -887,15 +904,25 @@ describe('CSFLE / QE', function () { name: '"Person Z"', }); - await browser.clickVisible(Selectors.FleConnectionConfigurationBanner); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + connectionName, + Selectors.Multiple.InUseEncryptionMarker + ) + ); + } else { + await browser.clickVisible(Selectors.Single.InUseEncryptionMarker); + } - modal = await browser.$(Selectors.CSFLEConnectionModal); - await modal.waitForDisplayed(); + await browser.$(Selectors.CSFLEConnectionModal).waitForDisplayed(); await browser.clickVisible(Selectors.SetCSFLEEnabledLabel); await browser.clickVisible(Selectors.CSFLEConnectionModalCloseButton); - await modal.waitForDisplayed({ reverse: true }); + await browser + .$(Selectors.CSFLEConnectionModal) + .waitForDisplayed({ reverse: true }); decryptedResult = await getFirstListDocument(browser); @@ -913,7 +940,6 @@ describe('CSFLE / QE', function () { describe('server version gte 6.0 and lt 7.0', function () { const databaseName = 'db-for-fle'; const collectionName = 'my-encrypted-collection'; - const connectionName = 'fle'; let compass: Compass; let browser: CompassBrowser; @@ -946,104 +972,83 @@ describe('CSFLE / QE', function () { connectionName, }); - await browser.shellEval(connectionName, `use ${databaseName}`); - - // insert the dataKey that was used to encrypt the payloads used below - await browser.shellEval( - connectionName, - 'dataKey = new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1");' - ); - await browser.shellEval( - connectionName, + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + // insert the dataKey that was used to encrypt the payloads used below + 'dataKey = new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1");', `db.getCollection("keyvault").insertOne({ - _id: new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1"), - keyMaterial: Binary.createFromHexString("519e2b15d20f00955a3960aab31e70a8e3fdb661129ef0d8a752291599488f8fda23ca64ddcbced93dbc715d03f45ab53a8e8273f2230c41c0e64d9ef746d6959cbdc1abcf0e9d020856e2da09a91ef129ac60ef13a98abcd5ee0cbfba21f1de153974996ab002bddccf7dc0268fed90a172dc373e90b63bc2369a5a1bfc78e0c2d7d81e65e970a38ca585248fef53b70452687024b8ecd308930a25414518e3", 0), - creationDate: ISODate("2023-05-05T10:58:12.473Z"), - updateDate: ISODate("2023-05-05T10:58:12.473Z"), - status: 0, - masterKey: { provider: 'local' } - });` - ); - - await browser.shellEval( - connectionName, + _id: new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1"), + keyMaterial: Binary.createFromHexString("519e2b15d20f00955a3960aab31e70a8e3fdb661129ef0d8a752291599488f8fda23ca64ddcbced93dbc715d03f45ab53a8e8273f2230c41c0e64d9ef746d6959cbdc1abcf0e9d020856e2da09a91ef129ac60ef13a98abcd5ee0cbfba21f1de153974996ab002bddccf7dc0268fed90a172dc373e90b63bc2369a5a1bfc78e0c2d7d81e65e970a38ca585248fef53b70452687024b8ecd308930a25414518e3", 0), + creationDate: ISODate("2023-05-05T10:58:12.473Z"), + updateDate: ISODate("2023-05-05T10:58:12.473Z"), + status: 0, + masterKey: { provider: 'local' } + });`, `db.runCommand({ - create: '${collectionName}', - encryptedFields: { - fields: [{ - keyId: dataKey, - path: 'v', - bsonType: 'string', - queries: [{ queryType: 'equality' }] - }] - } - });` - ); - - // these payloads were encrypted using dataKey - await browser.shellEval( - connectionName, - `db.runCommand({ - insert: '${collectionName}', - documents: [ - { - _id: 'asdf', - v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b1025438da7f9034a7d6bf03452c9b910381a16b4a0d52592ed6eafc64cc45dde441ac136269b4606f197e939fd54dd9fb257ce2c5afe94853b3b150a9101d65a3063f948ce05350fc4a5811eb5f29793dfd5a9cab77c680bba17f91845895cfd080c123e02a3f1c7e5d5c8c6448a0ac7d624669d0306be6fdcea35106062e742bec39a9873de969196ad95960d4bc247e98dc88a33d9c974646c8283178f3198749c7f24dbd66dc5e7ecf42efc08f64b6a646aa50e872a6f30907b54249039f3226af503d2e2e947323", 6), - __safeContent__: [ - Binary.createFromHexString("91865d04a1a1719e2ef89d66eeb8a35515f22470558831fe9494f011e9a209c3", 0) - ] - }, - { - _id: 'ghjk', - v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b10299f34210f149673b61f0d369f89290577c410b800ff38ed10eec235aef3677d3594c6371dd5b8f8d4c34769228bf7aea00b1754036a5850a4fef25c40969451151695614ae6142e954bab6c72080b5f43ccac774f6a1791bcc2ca4ca8998b9d5148441180631c7d8136034ff5019ca31a082464ec2fdcf212460a121d14dec3b8ee313541dc46689c79636929f0828dfdef7dfd4d53e1a924bbf70be34b1668d9352f6102a32265ec45d9c5cc0d7cf5f9266cf161497ee5b4a9495e16926b09282c6e4029d22d88e", 6), - __safeContent__: [ - Binary.createFromHexString("b04e26633d569cb47b9cbec650d812a597ffdadacb9a61ee7b1661f52228d661", 0) - ] + create: '${collectionName}', + encryptedFields: { + fields: [{ + keyId: dataKey, + path: 'v', + bsonType: 'string', + queries: [{ queryType: 'equality' }] + }] } - ], - bypassDocumentValidation: true - });` - ); - - await browser.shellEval( - connectionName, + });`, + // these payloads were encrypted using dataKey `db.runCommand({ - insert: 'enxcol_.${collectionName}.ecoc', - documents: [ - { - _id: ObjectId("6454e14689ef42f381f7336b"), - fieldName: 'v', - value: Binary.createFromHexString("3eb89d3a95cf955ca0c8c56e54018657a45daaf465dd967d9b24895a188d7e3055734f3c0af88302ceab460874f3806fe52fa4541c9f4b32b5cee6c5a6df9399da664f576dd9bde23bce92f5deea0cb3", 0) - }, - { - _id: ObjectId("6454e14689ef42f381f73385"), - fieldName: 'v', - value: Binary.createFromHexString("2299cd805a28efb6503120e0250798f1b19137d8234690d12eb7e3b7fa74edd28e80c26022c00d53f5983f16e7b5abb7c3b95e30f265a7ba36adb290eda39370b30cedba960a4002089eb5de2fd118fc", 0) - } - ], - bypassDocumentValidation: true - });` - ); - - await browser.shellEval( - connectionName, + insert: '${collectionName}', + documents: [ + { + _id: 'asdf', + v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b1025438da7f9034a7d6bf03452c9b910381a16b4a0d52592ed6eafc64cc45dde441ac136269b4606f197e939fd54dd9fb257ce2c5afe94853b3b150a9101d65a3063f948ce05350fc4a5811eb5f29793dfd5a9cab77c680bba17f91845895cfd080c123e02a3f1c7e5d5c8c6448a0ac7d624669d0306be6fdcea35106062e742bec39a9873de969196ad95960d4bc247e98dc88a33d9c974646c8283178f3198749c7f24dbd66dc5e7ecf42efc08f64b6a646aa50e872a6f30907b54249039f3226af503d2e2e947323", 6), + __safeContent__: [ + Binary.createFromHexString("91865d04a1a1719e2ef89d66eeb8a35515f22470558831fe9494f011e9a209c3", 0) + ] + }, + { + _id: 'ghjk', + v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b10299f34210f149673b61f0d369f89290577c410b800ff38ed10eec235aef3677d3594c6371dd5b8f8d4c34769228bf7aea00b1754036a5850a4fef25c40969451151695614ae6142e954bab6c72080b5f43ccac774f6a1791bcc2ca4ca8998b9d5148441180631c7d8136034ff5019ca31a082464ec2fdcf212460a121d14dec3b8ee313541dc46689c79636929f0828dfdef7dfd4d53e1a924bbf70be34b1668d9352f6102a32265ec45d9c5cc0d7cf5f9266cf161497ee5b4a9495e16926b09282c6e4029d22d88e", 6), + __safeContent__: [ + Binary.createFromHexString("b04e26633d569cb47b9cbec650d812a597ffdadacb9a61ee7b1661f52228d661", 0) + ] + } + ], + bypassDocumentValidation: true + });`, `db.runCommand({ - insert: 'enxcol_.${collectionName}.esc', - documents: [ - { - _id: Binary.createFromHexString("51db700df02cbbfa25498921f858d3a9d5568cabb97f7283e7b3c9d0e3520ac4", 0), - value: Binary.createFromHexString("dc7169f28df2c990551b098b8dec8f5b1bfeb65d3f40d0fdb241a518310674a6", 0) - }, - { - _id: Binary.createFromHexString("948b3d29e335485b0503ffc6ade6bfa6fce664c2a1d14790a523c09223da3f09", 0), - value: Binary.createFromHexString("7622097476c59c0ca5bf9d05a52fe725517e03ad811f6c073b0d0184a9d26131", 0) - } - ], - bypassDocumentValidation: true - });` - ); + insert: 'enxcol_.${collectionName}.ecoc', + documents: [ + { + _id: ObjectId("6454e14689ef42f381f7336b"), + fieldName: 'v', + value: Binary.createFromHexString("3eb89d3a95cf955ca0c8c56e54018657a45daaf465dd967d9b24895a188d7e3055734f3c0af88302ceab460874f3806fe52fa4541c9f4b32b5cee6c5a6df9399da664f576dd9bde23bce92f5deea0cb3", 0) + }, + { + _id: ObjectId("6454e14689ef42f381f73385"), + fieldName: 'v', + value: Binary.createFromHexString("2299cd805a28efb6503120e0250798f1b19137d8234690d12eb7e3b7fa74edd28e80c26022c00d53f5983f16e7b5abb7c3b95e30f265a7ba36adb290eda39370b30cedba960a4002089eb5de2fd118fc", 0) + } + ], + bypassDocumentValidation: true + });`, + `db.runCommand({ + insert: 'enxcol_.${collectionName}.esc', + documents: [ + { + _id: Binary.createFromHexString("51db700df02cbbfa25498921f858d3a9d5568cabb97f7283e7b3c9d0e3520ac4", 0), + value: Binary.createFromHexString("dc7169f28df2c990551b098b8dec8f5b1bfeb65d3f40d0fdb241a518310674a6", 0) + }, + { + _id: Binary.createFromHexString("948b3d29e335485b0503ffc6ade6bfa6fce664c2a1d14790a523c09223da3f09", 0), + value: Binary.createFromHexString("7622097476c59c0ca5bf9d05a52fe725517e03ad811f6c073b0d0184a9d26131", 0) + } + ], + bypassDocumentValidation: true + });`, + ]); - await browser.disconnect(); + await browser.disconnectAll(); // now connect with QE and check that we can query the data stored in a 6.x database await browser.connectWithConnectionForm({ diff --git a/packages/compass-e2e-tests/tests/instance-sidebar.test.ts b/packages/compass-e2e-tests/tests/instance-sidebar.test.ts index d7ffd2e488c..9ec8159be12 100644 --- a/packages/compass-e2e-tests/tests/instance-sidebar.test.ts +++ b/packages/compass-e2e-tests/tests/instance-sidebar.test.ts @@ -154,9 +154,16 @@ describe('Instance sidebar', function () { } // open the create database modal from the sidebar - await browser.clickVisible(Sidebar.CreateDatabaseButton, { - screenshot: 'before-can-create-a-database-and-drop-it-click.png', - }); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + connectionName, + Sidebar.CreateDatabaseButton + ) + ); + } else { + await browser.clickVisible(Sidebar.CreateDatabaseButton); + } await browser.addDatabase(dbName, collectionName); diff --git a/packages/compass-e2e-tests/tests/oidc.test.ts b/packages/compass-e2e-tests/tests/oidc.test.ts index c71809906a0..4d0296ef1ed 100644 --- a/packages/compass-e2e-tests/tests/oidc.test.ts +++ b/packages/compass-e2e-tests/tests/oidc.test.ts @@ -345,11 +345,11 @@ describe('OIDC integration', function () { ); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); await browser.selectConnection(favoriteName); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); const connectionInfo = await getFavoriteConnectionInfo(favoriteName); expect(connectionInfo?.connectionOptions?.oidc?.serializedState).to.be.a( @@ -369,7 +369,7 @@ describe('OIDC integration', function () { await browser.screenshot(`after-creating-favourite-${favoriteName}.png`); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); await browser.screenshot( `after-disconnecting-favourite-${favoriteName}.png` @@ -378,7 +378,7 @@ describe('OIDC integration', function () { // TODO(COMPASS-7810): when clicking on the favourite the element is somehow stale and then webdriverio throws await browser.selectConnection(favoriteName); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); const connectionInfo = await getFavoriteConnectionInfo(favoriteName); expect(connectionInfo?.connectionOptions?.oidc?.serializedState).to.equal( @@ -396,7 +396,7 @@ describe('OIDC integration', function () { ); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); const connectionInfo = await getFavoriteConnectionInfo(favoriteName); expect(connectionInfo?.connectionOptions?.oidc?.serializedState).to.be.a( @@ -412,7 +412,7 @@ describe('OIDC integration', function () { await browser.selectConnection(favoriteName); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); expect(oidcMockProviderEndpointAccesses['/authorize']).to.equal(1); }); diff --git a/packages/compass-e2e-tests/tests/read-only.test.ts b/packages/compass-e2e-tests/tests/read-only.test.ts index 0289abf9796..d1ab6da03dc 100644 --- a/packages/compass-e2e-tests/tests/read-only.test.ts +++ b/packages/compass-e2e-tests/tests/read-only.test.ts @@ -52,9 +52,16 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.navigateToConnectionTab(connectionName, 'Databases'); } - expect( - await browser.$(Sidebar.CreateDatabaseButton).isExisting() - ).to.be.equal(false); + const addDatabaseSelector = TEST_MULTIPLE_CONNECTIONS + ? Selectors.sidebarConnectionActionButton( + connectionName, + Sidebar.CreateDatabaseButton + ) + : Sidebar.CreateDatabaseButton; + + expect(await browser.$(addDatabaseSelector).isExisting()).to.be.equal( + false + ); await browser.openSettingsModal(); const settingsModal = await browser.$(Selectors.SettingsModal); @@ -71,9 +78,7 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.navigateToConnectionTab(connectionName, 'Databases'); } - expect( - await browser.$(Sidebar.CreateDatabaseButton).isExisting() - ).to.be.equal(true); + expect(await browser.$(addDatabaseSelector).isExisting()).to.be.equal(true); }); it('shows and hides the plus icon on the siderbar to create a collection', async function () { diff --git a/packages/compass-e2e-tests/tests/search-indexes.test.ts b/packages/compass-e2e-tests/tests/search-indexes.test.ts index a36c21e902a..0b854089e3b 100644 --- a/packages/compass-e2e-tests/tests/search-indexes.test.ts +++ b/packages/compass-e2e-tests/tests/search-indexes.test.ts @@ -10,7 +10,6 @@ import { TEST_COMPASS_WEB, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; -import { disconnect } from '../helpers/commands'; import { expect } from 'chai'; import { type Db, MongoClient } from 'mongodb'; @@ -205,7 +204,7 @@ describe.skip('Search Indexes', function () { } } void mongoClient.close(); - await disconnect(browser); + await browser.disconnectAll(); await screenshotIfFailed(compass, this.currentTest); });