diff --git a/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts b/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts index ebfc699cdf9..25b1ce6c7ba 100644 --- a/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts +++ b/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts @@ -1,9 +1,11 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; +import type { WorkspaceTabSelectorOptions } from '../selectors'; async function navigateToCollection( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account + connectionName: string, dbName: string, collectionName: string, @@ -12,7 +14,10 @@ async function navigateToCollection( // state of Schema, and Validation tabs without re-connecting. closeExistingTabs = true ): Promise { + const connectionId = await browser.getConnectionIdByName(connectionName); + const collectionSelector = Selectors.sidebarCollection( + connectionId, dbName, collectionName ); @@ -23,19 +28,27 @@ async function navigateToCollection( // search for the collection and wait for the collection to be there and visible await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, collectionName); + await browser.setValueVisible( + Selectors.SidebarFilterInput, + `^(${dbName}|${collectionName})$` + ); const collectionElement = await browser.$(collectionSelector); await collectionElement.waitForDisplayed(); // click it and wait for the collection header to become visible await browser.clickVisible(collectionSelector); - await waitUntilActiveCollectionTab(browser, dbName, collectionName); + await waitUntilActiveCollectionTab( + browser, + connectionName, + dbName, + collectionName + ); } export async function navigateToCollectionTab( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account + connectionName: string, dbName: string, collectionName: string, tabName: @@ -48,6 +61,7 @@ export async function navigateToCollectionTab( ): Promise { await navigateToCollection( browser, + connectionName, dbName, collectionName, closeExistingTabs @@ -57,7 +71,6 @@ export async function navigateToCollectionTab( export async function navigateWithinCurrentCollectionTabs( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account tabName: | 'Documents' | 'Aggregations' @@ -77,9 +90,9 @@ export async function navigateWithinCurrentCollectionTabs( await waitUntilActiveCollectionSubTab(browser, tabName); } -export async function waitUntilActiveCollectionTab( +async function waitUntilActiveCollectionTab( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account + connectionName: string, dbName: string, collectionName: string, tabName: @@ -90,9 +103,17 @@ export async function waitUntilActiveCollectionTab( | 'Validation' | null = null ) { - await browser - .$(Selectors.collectionWorkspaceTab(`${dbName}.${collectionName}`, true)) - .waitForDisplayed(); + const options: WorkspaceTabSelectorOptions = { + namespace: `${dbName}.${collectionName}`, + active: true, + }; + // Only add the connectionName for multiple connections because for some + // reason this sometimes flakes in single connections even though the tab is + // definitely there in the screenshot. + if (TEST_MULTIPLE_CONNECTIONS) { + options.connectionName = connectionName; + } + await browser.$(Selectors.workspaceTab(options)).waitForDisplayed(); if (tabName) { await waitUntilActiveCollectionSubTab(browser, tabName); } @@ -100,7 +121,6 @@ export async function waitUntilActiveCollectionTab( export async function waitUntilActiveCollectionSubTab( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account tabName: | 'Documents' | 'Aggregations' diff --git a/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts b/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts index baa80b08dfd..a59a2c88cfb 100644 --- a/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts +++ b/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts @@ -1,6 +1,7 @@ import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; +import type { WorkspaceTabSelectorOptions } from '../selectors'; export async function navigateToConnectionTab( browser: CompassBrowser, @@ -30,8 +31,13 @@ export async function waitUntilActiveConnectionTab( connectionName: string, tabName: 'Performance' | 'Databases' ) { - // TODO(COMPASS-8002): we should differentiate by connectionName somehow - await browser - .$(Selectors.connectionWorkspaceTab(tabName, true)) - .waitForDisplayed(); + const options: WorkspaceTabSelectorOptions = { title: tabName, active: true }; + + // Only add the connectionName for multiple connections because for some + // reason this sometimes flakes in single connections even though the tab is + // definitely there in the screenshot. + if (TEST_MULTIPLE_CONNECTIONS) { + options.connectionName = connectionName; + } + await browser.$(Selectors.workspaceTab(options)).waitForDisplayed(); } diff --git a/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts b/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts index 666d5caefd6..48bc4df4efc 100644 --- a/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts +++ b/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts @@ -1,5 +1,7 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; +import type { WorkspaceTabSelectorOptions } from '../selectors'; export async function navigateToDatabaseCollectionsTab( browser: CompassBrowser, @@ -16,8 +18,14 @@ export async function waitUntilActiveDatabaseTab( connectionName: string, dbName: string ) { - // TODO(COMPASS-8002): check that the connectionName matches too - await browser - .$(Selectors.databaseWorkspaceTab(dbName, true)) - .waitForDisplayed(); + const options: WorkspaceTabSelectorOptions = { title: dbName, active: true }; + + // Only add the connectionName for multiple connections because for some + // reason this sometimes flakes in single connections even though the tab is + // definitely there in the screenshot. + if (TEST_MULTIPLE_CONNECTIONS) { + options.connectionName = connectionName; + } + + await browser.$(Selectors.workspaceTab(options)).waitForDisplayed(); } diff --git a/packages/compass-e2e-tests/helpers/commands/disconnect.ts b/packages/compass-e2e-tests/helpers/commands/disconnect.ts index ca05add7e86..881a442d2fe 100644 --- a/packages/compass-e2e-tests/helpers/commands/disconnect.ts +++ b/packages/compass-e2e-tests/helpers/commands/disconnect.ts @@ -65,9 +65,13 @@ export async function disconnectAll( // toast by now. If so, just close it otherwise the next test or connection // attempt will be confused by it. if (await browser.$(Selectors.LGToastCloseButton).isExisting()) { - const toastText = await browser.$('#lg-toast-region').getText(); - debug('Closing toast', toastText); - await browser.clickVisible(Selectors.LGToastCloseButton); + try { + const toastText = await browser.$('#lg-toast-region').getText(); + debug('Closing toast', toastText); + await browser.clickVisible(Selectors.LGToastCloseButton); + } catch (error) { + debug('ignoring', error); + } } } diff --git a/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts b/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts index e60ee3f3e9e..900d81e9740 100644 --- a/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts +++ b/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts @@ -3,40 +3,25 @@ import * as Selectors from '../selectors'; export async function dropCollectionFromSidebar( browser: CompassBrowser, - dbName: string, + connectionName: string, + databaseName: string, collectionName: string ): Promise { - // search for the collecton in the sidebar filter - await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, collectionName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); - await dbElement.waitForDisplayed(); + await browser.selectCollectionMenuItem( + connectionName, + databaseName, + collectionName, + 'drop-collection' + ); + await browser.dropNamespace(collectionName); - // wait for the collection to become displayed + // wait for it to be gone + const connectionId = await browser.getConnectionIdByName(connectionName); const collectionSelector = Selectors.sidebarCollection( - dbName, + connectionId, + databaseName, collectionName ); - await browser.scrollToVirtualItem( - Selectors.SidebarNavigationTree, - collectionSelector, - 'tree' - ); const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); - - // open the drop collection modal from the sidebar - await browser.hover(collectionSelector); - - // NOTE: if the menu was already open for another collection this could get - // confusing. Also this selector is just for the actions button and it is - // assumed that at this point it is the only one. But the drop confirmation - // usually catches that. - await browser.clickVisible(Selectors.SidebarNavigationItemShowActionsButton); - await browser.clickVisible(Selectors.DropCollectionButton); - - await browser.dropNamespace(collectionName); - - // wait for it to be gone await collectionElement.waitForExist({ reverse: true }); } diff --git a/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts b/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts index 6ccb0be9a44..5b23a405abe 100644 --- a/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts +++ b/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts @@ -3,15 +3,20 @@ import * as Selectors from '../selectors'; export async function dropDatabaseFromSidebar( browser: CompassBrowser, + connectionName: string, dbName: string ): Promise { + const connectionId = await browser.getConnectionIdByName(connectionName); + // search for the database in the sidebar filter await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - await browser.$(Selectors.sidebarDatabase(dbName)).waitForDisplayed(); + await browser + .$(Selectors.sidebarDatabase(connectionId, dbName)) + .waitForDisplayed(); // open the drop database modal from the sidebar - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); await browser.clickVisible(Selectors.DropDatabaseButton); @@ -19,6 +24,6 @@ export async function dropDatabaseFromSidebar( // wait for it to be gone await browser - .$(Selectors.sidebarDatabase(dbName)) + .$(Selectors.sidebarDatabase(connectionId, dbName)) .waitForExist({ reverse: true }); } diff --git a/packages/compass-e2e-tests/helpers/commands/index.ts b/packages/compass-e2e-tests/helpers/commands/index.ts index 0abd5d31fa2..cac8d754db0 100644 --- a/packages/compass-e2e-tests/helpers/commands/index.ts +++ b/packages/compass-e2e-tests/helpers/commands/index.ts @@ -41,8 +41,7 @@ export * from './get-feature'; export * from './set-feature'; export * from './save-favorite'; export * from './save-connection-string-as-favorite'; -export * from './select-connection'; -export * from './select-connection-menu-item'; +export * from './sidebar-connection'; export * from './select-connections-menu-item'; export * from './open-settings-modal'; export * from './wait-for-connection-result'; @@ -67,4 +66,4 @@ export * from './drop-index'; export * from './hide-index'; export * from './unhide-index'; export * from './hide-visible-toasts'; -export * from './remove-connection'; +export * from './sidebar-collection'; diff --git a/packages/compass-e2e-tests/helpers/commands/remove-connection.ts b/packages/compass-e2e-tests/helpers/commands/remove-connection.ts deleted file mode 100644 index f63da9a928f..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/remove-connection.ts +++ /dev/null @@ -1,31 +0,0 @@ -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/select-connection-menu-item.ts b/packages/compass-e2e-tests/helpers/commands/select-connection-menu-item.ts deleted file mode 100644 index b744632cc4f..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/select-connection-menu-item.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; -import type { CompassBrowser } from '../compass-browser'; -import * as Selectors from '../selectors'; - -export async function selectConnectionMenuItem( - browser: CompassBrowser, - connectionName: string, - itemSelector: string -) { - const Sidebar = TEST_MULTIPLE_CONNECTIONS - ? Selectors.Multiple - : Selectors.Single; - - const selector = Selectors.sidebarConnection(connectionName); - - await browser.waitUntil(async () => { - if ( - await browser - .$(Selectors.sidebarConnectionMenuButton(connectionName)) - .isDisplayed() - ) { - return true; - } - - // It takes some time for the favourites to load - await browser.$(selector).waitForDisplayed(); - - // workaround for weirdness in the ItemActionControls menu opener icon - await browser.clickVisible(Sidebar.ConnectionsTitle); - - // Hover over an arbitrary other element to ensure that the second hover will - // actually be a fresh one. This otherwise breaks if this function is called - // twice in a row. - await browser.hover(`*:not(${selector}, ${selector} *)`); - - await browser.hover(selector); - return false; - }); - - await browser.clickVisible( - Selectors.sidebarConnectionMenuButton(connectionName) - ); - await browser.$(Sidebar.ConnectionMenu).waitForDisplayed(); - await browser.clickVisible(itemSelector); -} diff --git a/packages/compass-e2e-tests/helpers/commands/select-connection.ts b/packages/compass-e2e-tests/helpers/commands/select-connection.ts deleted file mode 100644 index 7731c82fadd..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/select-connection.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; -import type { CompassBrowser } from '../compass-browser'; -import * as Selectors from '../selectors'; - -export async function selectConnection( - browser: CompassBrowser, - connectionName: string -): Promise { - if (TEST_MULTIPLE_CONNECTIONS) { - await browser.selectConnectionMenuItem( - connectionName, - Selectors.Multiple.EditConnectionItem - ); - } else { - await browser.pause(1000); - - await browser.clickVisible( - Selectors.sidebarConnectionButton(connectionName), - { - screenshot: `selecting-connection-${connectionName}.png`, - } - ); - } - - await browser.waitUntil(async () => { - const connectionTitleSelector = TEST_MULTIPLE_CONNECTIONS - ? Selectors.ConnectionModalTitle - : Selectors.ConnectionTitle; - - const text = await browser.$(connectionTitleSelector).getText(); - return text === connectionName; - }); -} diff --git a/packages/compass-e2e-tests/helpers/commands/sidebar-collection.ts b/packages/compass-e2e-tests/helpers/commands/sidebar-collection.ts new file mode 100644 index 00000000000..b3926034ca3 --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/sidebar-collection.ts @@ -0,0 +1,54 @@ +import type { CompassBrowser } from '../compass-browser'; +import * as Selectors from '../selectors'; + +export async function selectCollectionMenuItem( + browser: CompassBrowser, + connectionName: string, + databaseName: string, + collectionName: string, + actionName: string +) { + const connectionId = await browser.getConnectionIdByName(connectionName); + + // search for the view in the sidebar + await browser.clickVisible(Selectors.SidebarFilterInput); + await browser.setValueVisible( + Selectors.SidebarFilterInput, + `^(${databaseName}|${collectionName})$` + ); + + const collectionSelector = Selectors.sidebarCollection( + connectionId, + databaseName, + collectionName + ); + + // scroll to the collection if necessary + await browser.scrollToVirtualItem( + Selectors.SidebarNavigationTree, + collectionSelector, + 'tree' + ); + + const collectionElement = await browser.$(collectionSelector); + await collectionElement.waitForDisplayed(); + + // hover over the collection + await browser.hover(collectionSelector); + + // click the show collections button + // NOTE: This assumes it is currently closed + await browser.clickVisible( + `${collectionSelector} ${Selectors.SidebarNavigationItemShowActionsButton}` + ); + + const actionSelector = `[role="menuitem"][data-action="${actionName}"]`; + + const actionButton = await browser.$(actionSelector); + + // click the action + await browser.clickVisible(actionSelector); + + // make sure the menu closed + await actionButton.waitForDisplayed({ reverse: true }); +} diff --git a/packages/compass-e2e-tests/helpers/commands/sidebar-connection.ts b/packages/compass-e2e-tests/helpers/commands/sidebar-connection.ts new file mode 100644 index 00000000000..0a395f712ff --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/sidebar-connection.ts @@ -0,0 +1,128 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; +import type { CompassBrowser } from '../compass-browser'; +import * as Selectors from '../selectors'; + +export async function getConnectionIdByName( + browser: CompassBrowser, + connectionName: string +): Promise { + if (!TEST_MULTIPLE_CONNECTIONS) { + // the connection id isn't somewhere we can consistently access it in the + // single connection world + return undefined; + } + + const connections = await browser.$$( + Selectors.sidebarConnection(connectionName) + ); + + if (connections.length !== 1) { + throw new Error( + `Found ${connections.length} connections named ${connectionName}.` + ); + } + + return await browser + .$(Selectors.sidebarConnection(connectionName)) + .getAttribute('data-connection-id'); +} + +export async function selectConnection( + browser: CompassBrowser, + connectionName: string +): Promise { + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.EditConnectionItem + ); + } else { + await browser.pause(1000); + + await browser.clickVisible( + Selectors.sidebarConnectionButton(connectionName), + { + screenshot: `selecting-connection-${connectionName}.png`, + } + ); + } + + await browser.waitUntil(async () => { + const connectionTitleSelector = TEST_MULTIPLE_CONNECTIONS + ? Selectors.ConnectionModalTitle + : Selectors.ConnectionTitle; + + const text = await browser.$(connectionTitleSelector).getText(); + return text === connectionName; + }); +} + +export async function selectConnectionMenuItem( + browser: CompassBrowser, + connectionName: string, + itemSelector: string +) { + const Sidebar = TEST_MULTIPLE_CONNECTIONS + ? Selectors.Multiple + : Selectors.Single; + + const selector = Selectors.sidebarConnection(connectionName); + + await browser.waitUntil(async () => { + if ( + await browser + .$(Selectors.sidebarConnectionMenuButton(connectionName)) + .isDisplayed() + ) { + return true; + } + + // It takes some time for the favourites to load + await browser.$(selector).waitForDisplayed(); + + // workaround for weirdness in the ItemActionControls menu opener icon + await browser.clickVisible(Sidebar.ConnectionsTitle); + + // Hover over an arbitrary other element to ensure that the second hover will + // actually be a fresh one. This otherwise breaks if this function is called + // twice in a row. + await browser.hover(`*:not(${selector}, ${selector} *)`); + + await browser.hover(selector); + return false; + }); + + await browser.clickVisible( + Selectors.sidebarConnectionMenuButton(connectionName) + ); + await browser.$(Sidebar.ConnectionMenu).waitForDisplayed(); + await browser.clickVisible(itemSelector); +} + +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/workspace-tabs.ts b/packages/compass-e2e-tests/helpers/commands/workspace-tabs.ts index a97bc2b396a..ecb9b0e169e 100644 --- a/packages/compass-e2e-tests/helpers/commands/workspace-tabs.ts +++ b/packages/compass-e2e-tests/helpers/commands/workspace-tabs.ts @@ -1,6 +1,8 @@ import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; import type { WorkspaceTabSelectorOptions } from '../selectors'; +import Debug from 'debug'; +const debug = Debug('compass-e2e-tests'); export async function navigateToMyQueries(browser: CompassBrowser) { await browser.clickVisible(Selectors.SidebarMyQueriesTab); @@ -14,31 +16,36 @@ async function closeTab( selectorOptions: WorkspaceTabSelectorOptions, autoConfirmTabClose: boolean ): Promise { - await browser.clickVisible( - browser - .$(Selectors.workspaceTab(selectorOptions)) - .$(Selectors.CloseWorkspaceTab) - ); - // wait until the tab goes away and if the confirmation modal opens, maybe confirm - await browser.waitUntil(async () => { - if (autoConfirmTabClose) { - // Tabs in "dirty" state can't be closed without confirmation - if (await browser.$(Selectors.ConfirmTabCloseModal).isExisting()) { - await browser.clickVisible( - browser.$(Selectors.ConfirmTabCloseModal).$('button=Close tab') - ); - await browser - .$(Selectors.ConfirmTabCloseModal) - .waitForDisplayed({ reverse: true }); + await browser.waitUntil( + async () => { + // keep retrying the click :( + await browser.clickVisible( + browser + .$(Selectors.workspaceTab(selectorOptions)) + .$(Selectors.CloseWorkspaceTab) + ); + + if (autoConfirmTabClose) { + // Tabs in "dirty" state can't be closed without confirmation + if (await browser.$(Selectors.ConfirmTabCloseModal).isExisting()) { + await browser.clickVisible( + browser.$(Selectors.ConfirmTabCloseModal).$('button=Close tab') + ); + await browser + .$(Selectors.ConfirmTabCloseModal) + .waitForDisplayed({ reverse: true }); + } } - } - return ( - (await browser - .$(Selectors.workspaceTab(selectorOptions)) - .isExisting()) === false - ); - }); + return ( + (await browser + .$(Selectors.workspaceTab(selectorOptions)) + .isExisting()) === false + ); + }, + // Don't wait longer than the wait in closeWorkspaceTabs + { timeout: 10_000 } + ); } export async function closeWorkspaceTabs( @@ -50,7 +57,8 @@ export async function closeWorkspaceTabs( }; await browser.waitUntil(async () => { - if ((await countTabs()) > 0) { + const numTabsStart = await countTabs(); + if (numTabsStart > 0) { const currentActiveTab = await browser.$( Selectors.workspaceTab({ active: true }) ); @@ -59,10 +67,15 @@ export async function closeWorkspaceTabs( // are multiple tabs then another tab will immediately become active and // trip up the logic that checks that the tab you closed went away. const id = await currentActiveTab.getAttribute('id'); + debug('closing tab', { numTabsStart, id }); await closeTab(browser, { id }, autoConfirmTabClose); + + const numTabsEnd = await countTabs(); + debug('after closing tab', { id, numTabsStart, numTabsEnd }); + return numTabsEnd === 0; + } else { + return true; } - const numTabs = await countTabs(); - return numTabs === 0; }); } diff --git a/packages/compass-e2e-tests/helpers/compass.ts b/packages/compass-e2e-tests/helpers/compass.ts index 4a88b255d6e..ed9c4cd41c1 100644 --- a/packages/compass-e2e-tests/helpers/compass.ts +++ b/packages/compass-e2e-tests/helpers/compass.ts @@ -77,6 +77,9 @@ export const MONGODB_TEST_SERVER_PORT = Number( ); export const DEFAULT_CONNECTION_STRING = `mongodb://127.0.0.1:${MONGODB_TEST_SERVER_PORT}/test`; +export const DEFAULT_CONNECTION_NAME = connectionNameFromString( + DEFAULT_CONNECTION_STRING +); export function updateMongoDBServerInfo() { try { diff --git a/packages/compass-e2e-tests/helpers/selectors.ts b/packages/compass-e2e-tests/helpers/selectors.ts index e78a829c209..c2533d63d5e 100644 --- a/packages/compass-e2e-tests/helpers/selectors.ts +++ b/packages/compass-e2e-tests/helpers/selectors.ts @@ -332,21 +332,36 @@ export const RenameCollectionButton = '[data-testid="sidebar-navigation-item-actions-rename-collection-action"]'; export const DropDatabaseButton = '[data-action="drop-database"]'; export const CreateCollectionButton = '[data-action="create-collection"]'; -export const DropCollectionButton = '[data-action="drop-collection"]'; export const DatabaseCollectionPlaceholder = '[data-testid="placeholder"]'; -export const sidebarDatabase = (dbName: string): string => { +export const sidebarDatabase = ( + // TODO(COMPASS-7906): don't allow undefined connectionId + connectionId: string | undefined, + dbName: string +): string => { + if (connectionId) { + return `${Sidebar} [data-connection-id="${connectionId}"][data-database-name="${dbName}"]`; + } return `${Sidebar} [data-database-name="${dbName}"]`; }; -export const sidebarDatabaseToggle = (dbName: string): string => { - return `${sidebarDatabase(dbName)} button[type=button]`; +export const sidebarDatabaseToggle = ( + // TODO(COMPASS-7906): don't allow undefined connectionId + connectionId: string | undefined, + dbName: string +): string => { + return `${sidebarDatabase(connectionId, dbName)} button[type=button]`; }; export const sidebarCollection = ( + // TODO(COMPASS-7906): don't allow undefined connectionId + connectionId: string | undefined, dbName: string, collectionName: string ): string => { + if (connectionId) { + return `${Sidebar} [data-connection-id="${connectionId}"][data-namespace="${dbName}.${collectionName}"]`; + } return `${Sidebar} [data-namespace="${dbName}.${collectionName}"]`; }; @@ -1230,18 +1245,6 @@ export const workspaceTab = ({ } return parts.join(''); }; -export const connectionWorkspaceTab = ( - tabName: 'Performance' | 'Databases', - active?: boolean -) => { - return workspaceTab({ title: tabName, active }); -}; -export const databaseWorkspaceTab = (dbName: string, active?: boolean) => { - return workspaceTab({ title: dbName, active }); -}; -export const collectionWorkspaceTab = (namespace: string, active: boolean) => { - return workspaceTab({ namespace, active }); -}; // Export modal export const ExportModal = '[data-testid="export-modal"]'; diff --git a/packages/compass-e2e-tests/tests/atlas-login.test.ts b/packages/compass-e2e-tests/tests/atlas-login.test.ts index c432a664304..c1128bd76b7 100644 --- a/packages/compass-e2e-tests/tests/atlas-login.test.ts +++ b/packages/compass-e2e-tests/tests/atlas-login.test.ts @@ -6,6 +6,7 @@ import { Selectors, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import type { OIDCMockProviderConfig } from '@mongodb-js/oidc-mock-provider'; @@ -273,7 +274,12 @@ describe('Atlas Login', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); it('should not show AI input if sign in flow was not finished', async function () { @@ -300,7 +306,12 @@ describe('Atlas Login', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); }); it('should not show AI input if sign in flow was not finished', async function () { diff --git a/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts b/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts index 2425cd084a1..54105136088 100644 --- a/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts @@ -8,6 +8,7 @@ import { outputFilename, serverSatisfies, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -69,49 +70,6 @@ async function getDocuments(browser: CompassBrowser) { }); } -async function chooseCollectionAction( - browser: CompassBrowser, - dbName: string, - collectionName: string, - actionName: string -) { - // search for the view in the sidebar - await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, collectionName); - - const collectionSelector = Selectors.sidebarCollection( - dbName, - collectionName - ); - - // scroll to the collection if necessary - await browser.scrollToVirtualItem( - Selectors.SidebarNavigationTree, - collectionSelector, - 'tree' - ); - - const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); - - // hover over the collection - await browser.hover(collectionSelector); - - // click the show collections button - // NOTE: This assumes it is currently closed - await browser.clickVisible(Selectors.SidebarNavigationItemShowActionsButton); - - const actionSelector = `[role="menuitem"][data-action="${actionName}"]`; - - const actionButton = await browser.$(actionSelector); - - // click the action - await browser.clickVisible(actionSelector); - - // make sure the menu closed - await actionButton.waitForDisplayed({ reverse: true }); -} - async function waitForTab(browser: CompassBrowser, namespace: string) { await browser.waitUntil( async function () { @@ -176,7 +134,12 @@ describe('Collection aggregations tab', function () { }, STAGE_WIZARD_GUIDE_CUE_STORAGE_KEY); // Some tests navigate away from the numbers collection aggregations tab - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); // Get us back to the empty stage every time. Also test the Create New // Pipeline flow while at it. await browser.clickVisible(Selectors.CreateNewPipelineButton); @@ -468,8 +431,8 @@ describe('Collection aggregations tab', function () { await waitForTab(browser, 'test.my-view-from-pipeline'); // choose Duplicate view - await chooseCollectionAction( - browser, + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, 'test', 'my-view-from-pipeline', 'duplicate-view' @@ -496,8 +459,8 @@ describe('Collection aggregations tab', function () { await waitForTab(browser, 'test.duplicated-view'); // now select modify view of the non-duplicate - await chooseCollectionAction( - browser, + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, 'test', 'my-view-from-pipeline', 'modify-view' @@ -509,6 +472,7 @@ describe('Collection aggregations tab', function () { // make sure we're on the aggregations tab, in edit mode const modifyBanner = await browser.$(Selectors.ModifySourceBanner); await modifyBanner.waitForDisplayed(); + expect(await modifyBanner.getText()).to.equal( 'MODIFYING PIPELINE BACKING "TEST.MY-VIEW-FROM-PIPELINE"' ); @@ -1627,6 +1591,7 @@ describe('Collection aggregations tab', function () { describe('expanding and collapsing of documents', function () { beforeEach(async function () { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'nestedDocs', 'Aggregations' diff --git a/packages/compass-e2e-tests/tests/collection-ai-query.test.ts b/packages/compass-e2e-tests/tests/collection-ai-query.test.ts index 3c4a88dd346..cfd3bc70036 100644 --- a/packages/compass-e2e-tests/tests/collection-ai-query.test.ts +++ b/packages/compass-e2e-tests/tests/collection-ai-query.test.ts @@ -9,6 +9,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -56,7 +57,12 @@ describe('Collection ai query', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts b/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts index 090c8b7b796..1579a9f7230 100644 --- a/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts +++ b/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts @@ -2,7 +2,12 @@ import { expect } from 'chai'; import type { CompassBrowser } from '../helpers/compass-browser'; import { startTelemetryServer } from '../helpers/telemetry'; import type { Telemetry } from '../helpers/telemetry'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -26,7 +31,12 @@ describe('Bulk Delete', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); afterEach(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts index d2106638e79..583c98b7fd9 100644 --- a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts +++ b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts @@ -7,6 +7,7 @@ import { cleanup, screenshotIfFailed, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -31,7 +32,12 @@ describe('Bulk Update', () => { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); afterEach(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts b/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts index d645f4ac801..f025bf37eb2 100644 --- a/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts @@ -9,6 +9,7 @@ import { screenshotIfFailed, TEST_COMPASS_WEB, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -122,7 +123,12 @@ describe('Collection documents tab', function () { await createNumbersCollection(); await createNestedDocumentsCollection('nestedDocs', 10); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); if (!TEST_COMPASS_WEB) { // setFeature/getFeature is not supported in compass-web yet @@ -630,7 +636,12 @@ FindIterable result = collection.find(filter);`); describe('expanding and collapsing of documents', function () { beforeEach(async function () { - await browser.navigateToCollectionTab('test', 'nestedDocs', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'nestedDocs', + 'Documents' + ); }); it('expands and collapses all fields in a document', async function () { diff --git a/packages/compass-e2e-tests/tests/collection-export.test.ts b/packages/compass-e2e-tests/tests/collection-export.test.ts index a525c73c347..f557dde6383 100644 --- a/packages/compass-e2e-tests/tests/collection-export.test.ts +++ b/packages/compass-e2e-tests/tests/collection-export.test.ts @@ -10,6 +10,7 @@ import { outputFilename, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -67,7 +68,12 @@ describe('Collection export', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); it('supports collection to CSV with a query filter with a subset of fields', async function () { @@ -879,6 +885,7 @@ describe('Collection export', function () { await createNumbersStringCollection(); await browser.connectWithConnectionString(); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'numbers-strings', 'Documents' diff --git a/packages/compass-e2e-tests/tests/collection-heading.test.ts b/packages/compass-e2e-tests/tests/collection-heading.test.ts index e719d6bc2d5..0da2ad865be 100644 --- a/packages/compass-e2e-tests/tests/collection-heading.test.ts +++ b/packages/compass-e2e-tests/tests/collection-heading.test.ts @@ -1,6 +1,11 @@ import { expect } from 'chai'; import type { CompassBrowser } from '../helpers/compass-browser'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -17,7 +22,12 @@ describe('Collection heading', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-import.test.ts b/packages/compass-e2e-tests/tests/collection-import.test.ts index cdb6c0f0b06..2bd217da580 100644 --- a/packages/compass-e2e-tests/tests/collection-import.test.ts +++ b/packages/compass-e2e-tests/tests/collection-import.test.ts @@ -9,6 +9,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import { getFirstListDocument } from '../helpers/read-first-document-content'; import type { Compass } from '../helpers/compass'; @@ -125,7 +126,12 @@ describe('Collection import', function () { }); it('supports single JSON objects', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); async function getDocumentCount() { const countText = await browser @@ -201,7 +207,12 @@ describe('Collection import', function () { }); it('supports single objects in document view mode', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); // browse to the "Insert to Collection" modal await browser.clickVisible(Selectors.AddDataButton); @@ -272,7 +283,12 @@ describe('Collection import', function () { }); it('supports JSON arrays', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); const array = []; for (let i = 0; i < 1000; ++i) { @@ -328,7 +344,12 @@ describe('Collection import', function () { }); it('displays an error for a malformed JSON array', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); const json = 'this is not valid JSON'; @@ -364,7 +385,12 @@ describe('Collection import', function () { it('supports JSON files', async function () { const jsonPath = path.resolve(__dirname, '..', 'fixtures', 'listings.json'); - await browser.navigateToCollectionTab('test', 'json-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-file', + 'Documents' + ); await importJSONFile(browser, jsonPath); @@ -410,6 +436,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'extended-json-file', 'Documents' @@ -460,6 +487,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'extended-json-file', 'Documents' @@ -501,7 +529,12 @@ describe('Collection import', function () { it('supports CSV files', async function () { const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); - await browser.navigateToCollectionTab('test', 'csv-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'csv-file', + 'Documents' + ); // open the import modal await browser.clickVisible(Selectors.AddDataButton); @@ -628,6 +661,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'array-documents', 'Documents' @@ -841,7 +875,12 @@ describe('Collection import', function () { 'source-with-bom.csv' ); - await browser.navigateToCollectionTab('test', 'bom-csv-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'bom-csv-file', + 'Documents' + ); // open the import modal await browser.clickVisible(Selectors.AddDataButton); @@ -928,7 +967,12 @@ describe('Collection import', function () { it('displays an error if an incompatible type is chosen for a column', async function () { const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); - await browser.navigateToCollectionTab('test', 'csv-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'csv-file', + 'Documents' + ); // open the import modal await browser.clickVisible(Selectors.AddDataButton); @@ -983,6 +1027,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'broken-delimiter', 'Documents' @@ -1072,6 +1117,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'import-stop-first-error', 'Documents' @@ -1127,6 +1173,7 @@ describe('Collection import', function () { const jsonPath = path.resolve(__dirname, '..', 'fixtures', fileName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'import-with-errors', 'Documents' @@ -1197,6 +1244,7 @@ describe('Collection import', function () { const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'compass-import-abort-e2e-test', 'Documents' @@ -1272,6 +1320,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'compass-import-abort-e2e-test', 'Documents' @@ -1338,6 +1387,7 @@ describe('Collection import', function () { const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'compass-import-abort-e2e-test', 'Documents' diff --git a/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts b/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts index 7724ec43315..dcfa01bd62f 100644 --- a/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts @@ -6,6 +6,7 @@ import { cleanup, screenshotIfFailed, serverSatisfies, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -25,7 +26,12 @@ describe('Collection indexes tab', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Indexes' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-rename.test.ts b/packages/compass-e2e-tests/tests/collection-rename.test.ts index b6271a74c31..ee4fc9c539f 100644 --- a/packages/compass-e2e-tests/tests/collection-rename.test.ts +++ b/packages/compass-e2e-tests/tests/collection-rename.test.ts @@ -6,6 +6,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { CompassBrowser } from '../helpers/compass-browser'; import { createBlankCollection, dropDatabase } from '../helpers/insert-data'; @@ -56,32 +57,6 @@ class RenameCollectionModal { } } -async function navigateToCollectionInSidebar(browser: CompassBrowser) { - const sidebar = await browser.$(Selectors.SidebarNavigationTree); - await sidebar.waitForDisplayed(); - - // open the database in the sidebar - const dbElement = await browser.$(Selectors.sidebarDatabase(databaseName)); - await dbElement.waitForDisplayed(); - const button = await browser.$(Selectors.sidebarDatabaseToggle(databaseName)); - - await button.waitForDisplayed(); - await button.click(); - - // wait for the collection to become displayed - const collectionSelector = Selectors.sidebarCollection( - databaseName, - initialName - ); - await browser.scrollToVirtualItem( - Selectors.SidebarNavigationTree, - collectionSelector, - 'tree' - ); - const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); -} - async function renameCollectionSuccessFlow( browser: CompassBrowser, newName: string @@ -106,6 +81,7 @@ async function renameCollectionSuccessFlow( describe('Collection Rename Modal', () => { let compass: Compass; let browser: CompassBrowser; + let connectionId: string | undefined; before(async function () { skipForWeb(this, 'feature flags not yet available in compass-web'); @@ -123,6 +99,7 @@ describe('Collection Rename Modal', () => { await createBlankCollection(databaseName, 'bar'); await browser.connectWithConnectionString(); + connectionId = await browser.getConnectionIdByName(DEFAULT_CONNECTION_NAME); }); after(async function () { @@ -139,50 +116,34 @@ describe('Collection Rename Modal', () => { }); describe('from the sidebar', () => { - it('a collection can be renamed', async () => { - await navigateToCollectionInSidebar(browser); - - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton - ); - await browser.clickVisible(Selectors.RenameCollectionButton); - - // go through - await renameCollectionSuccessFlow(browser, newName); - - // confirm that the new collection name is shown in the sidebar - await browser - .$(Selectors.sidebarCollection(databaseName, newName)) - .waitForDisplayed(); - }); - it('collection rename shows up on collection view', async () => { - await navigateToCollectionInSidebar(browser); // open a collection tab - const collectionSelector = Selectors.sidebarCollection( + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, initialName ); - const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); - await collectionElement.click(); const headerSelector = Selectors.CollectionHeader; // wait until the collection tab has loaded await browser.$(headerSelector).waitForDisplayed(); - // open the rename collection flow from the sidebar - await browser.hover(collectionSelector); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); + await renameCollectionSuccessFlow(browser, newName); + // confirm that the new collection name is shown in the sidebar + await browser.setValueVisible(Selectors.SidebarFilterInput, ''); + await browser + .$(Selectors.sidebarCollection(connectionId, databaseName, newName)) + .waitForDisplayed(); + + // confirm that the header in the workspace changes await browser.$(headerSelector).waitForDisplayed(); await browser.waitUntil(async () => { const collectionHeaderContent = await browser @@ -196,16 +157,12 @@ describe('Collection Rename Modal', () => { }); it('collection rename can be retried after an error renaming the collection', async () => { - await navigateToCollectionInSidebar(browser); - - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); // wait for the collection modal to appear const modal = new RenameCollectionModal(browser); @@ -234,34 +191,13 @@ describe('Collection Rename Modal', () => { }); describe('modal dismiss', () => { - it('the modal can be dismissed', async () => { - await navigateToCollectionInSidebar(browser); - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton - ); - await browser.clickVisible(Selectors.RenameCollectionButton); - // wait for the collection modal to appear - const modal = new RenameCollectionModal(browser); - await modal.isVisible(); - - await browser.clickVisible(modal.dismissButton); - await modal.isNotVisible(); - }); - it('clears modal state when dismissed', async () => { - await navigateToCollectionInSidebar(browser); - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); // wait for the collection modal to appear const modal = new RenameCollectionModal(browser); @@ -273,14 +209,12 @@ describe('Collection Rename Modal', () => { await modal.isNotVisible(); // re-open the modal - // open the drop collection modal from the sidebar - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); // assert that the form state has reset expect(await modal.collectionNameInput.getValue()).to.equal(initialName); diff --git a/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts b/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts index 8b0514f0b32..fe9d291edc9 100644 --- a/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts @@ -5,6 +5,7 @@ import { cleanup, screenshotIfFailed, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -39,7 +40,12 @@ describe('Collection schema tab', function () { }); it('analyzes a schema', async function () { - await browser.navigateToCollectionTab('test', 'numbers', 'Schema'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Schema' + ); await browser.clickVisible(Selectors.AnalyzeSchemaButton); const element = await browser.$(Selectors.SchemaFieldList); @@ -70,7 +76,12 @@ describe('Collection schema tab', function () { skipForWeb(this, "can't toggle features in compass-web"); await browser.setFeature('enableMaps', enableMaps); - await browser.navigateToCollectionTab('test', 'geospatial', 'Schema'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'geospatial', + 'Schema' + ); await browser.clickVisible(Selectors.AnalyzeSchemaButton); const element = await browser.$(Selectors.SchemaFieldList); diff --git a/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts b/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts index 73ba6ff1f9d..f3ac21a0d1b 100644 --- a/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts @@ -1,5 +1,10 @@ import type { CompassBrowser } from '../helpers/compass-browser'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -22,7 +27,12 @@ describe('Collection validation tab', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Validation'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Validation' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/connection.test.ts b/packages/compass-e2e-tests/tests/connection.test.ts index 5ec33bbbce5..7d2e9758ebd 100644 --- a/packages/compass-e2e-tests/tests/connection.test.ts +++ b/packages/compass-e2e-tests/tests/connection.test.ts @@ -15,8 +15,8 @@ import { TEST_COMPASS_WEB, TEST_MULTIPLE_CONNECTIONS, connectionNameFromString, + DEFAULT_CONNECTION_NAME, MONGODB_TEST_SERVER_PORT, - DEFAULT_CONNECTION_STRING, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import type { ConnectFormState } from '../helpers/connect-form-state'; @@ -128,12 +128,16 @@ function generateIamSessionToken(): { async function assertCanReadData( browser: CompassBrowser, - // TODO(COMPASS-8002): take into account connectionName connectionName: string, dbName: string, collectionName: string ): Promise { - await browser.navigateToCollectionTab(dbName, collectionName, 'Documents'); + await browser.navigateToCollectionTab( + connectionName, + dbName, + collectionName, + 'Documents' + ); await browser.waitUntil(async () => { const text = await browser .$(Selectors.DocumentListActionBarMessage) @@ -144,12 +148,16 @@ async function assertCanReadData( async function assertCannotInsertData( browser: CompassBrowser, - // TODO(COMPASS-8002): take into account connectionName connectionName: string, dbName: string, collectionName: string ): Promise { - await browser.navigateToCollectionTab(dbName, collectionName, 'Documents'); + await browser.navigateToCollectionTab( + connectionName, + dbName, + collectionName, + 'Documents' + ); // browse to the "Insert to Collection" modal await browser.clickVisible(Selectors.AddDataButton); @@ -239,17 +247,20 @@ async function assertCannotCreateDb( async function assertCannotCreateCollection( browser: CompassBrowser, - // TODO(COMPASS-8002): take into account connectionName connectionName: string, dbName: string, collectionName: string ): Promise { + const connectionId = await browser.getConnectionIdByName(connectionName); + // open create collection modal from the sidebar await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); await browser.clickVisible(Selectors.CreateCollectionButton); const createModalElement = await browser.$(Selectors.CreateCollectionModal); @@ -300,7 +311,7 @@ describe('Connection string', function () { await browser.connectWithConnectionString(); if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'db.runCommand({ connectionStatus: 1 })', true ); diff --git a/packages/compass-e2e-tests/tests/database-collections-tab.test.ts b/packages/compass-e2e-tests/tests/database-collections-tab.test.ts index 18c5cf97970..08ad3d2bdba 100644 --- a/packages/compass-e2e-tests/tests/database-collections-tab.test.ts +++ b/packages/compass-e2e-tests/tests/database-collections-tab.test.ts @@ -7,7 +7,7 @@ import { screenshotIfFailed, serverSatisfies, DEFAULT_CONNECTION_STRING, - connectionNameFromString, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -60,7 +60,7 @@ describe('Database collections tab', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); }); @@ -132,7 +132,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -170,10 +170,7 @@ describe('Database collections tab', function () { // the app should still be on the database Collections tab because there are // other collections in this database - await browser.waitUntilActiveDatabaseTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'test' - ); + await browser.waitUntilActiveDatabaseTab(DEFAULT_CONNECTION_NAME, 'test'); }); it('can create a capped collection', async function () { @@ -193,7 +190,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -234,7 +231,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -270,7 +267,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -307,7 +304,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -342,7 +339,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -353,7 +350,12 @@ describe('Database collections tab', function () { '[data-testid="collection-badge-clustered"]' ); - await browser.navigateToCollectionTab('test', collectionName, 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + collectionName, + 'Indexes' + ); const typeElementSelector = `${Selectors.indexComponent(indexName)} ${ Selectors.IndexFieldType @@ -377,10 +379,7 @@ describe('Database collections tab', function () { await mongoClient.close(); } - await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - db - ); + await browser.navigateToDatabaseCollectionsTab(DEFAULT_CONNECTION_NAME, db); await browser.clickVisible(Selectors.DatabaseRefreshCollectionButton); const collSelector = Selectors.collectionCard(db, coll); 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 28b797be154..088dc3fa66e 100644 --- a/packages/compass-e2e-tests/tests/in-use-encryption.test.ts +++ b/packages/compass-e2e-tests/tests/in-use-encryption.test.ts @@ -7,6 +7,7 @@ import { serverSatisfies, skipForWeb, TEST_MULTIPLE_CONNECTIONS, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -287,6 +288,7 @@ describe('CSFLE / QE', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -426,6 +428,7 @@ describe('CSFLE / QE', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -449,6 +452,7 @@ describe('CSFLE / QE', function () { await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -511,6 +515,7 @@ describe('CSFLE / QE', function () { await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -558,6 +563,7 @@ describe('CSFLE / QE', function () { await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, coll, 'Documents' @@ -627,6 +633,7 @@ describe('CSFLE / QE', function () { await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -694,6 +701,7 @@ describe('CSFLE / QE', function () { await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -776,6 +784,7 @@ describe('CSFLE / QE', function () { await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -859,6 +868,7 @@ describe('CSFLE / QE', function () { await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -1059,6 +1069,7 @@ describe('CSFLE / QE', function () { }); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' diff --git a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts index 3a2910d60dd..93a9844814f 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -5,8 +5,8 @@ import { init, cleanup, screenshotIfFailed, - connectionNameFromString, DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -30,10 +30,7 @@ describe('Instance databases tab', function () { await createDummyCollections(); await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); }); after(async function () { @@ -103,10 +100,7 @@ describe('Instance databases tab', function () { 'add-database-modal-basic.png' ); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); const selector = Selectors.databaseCard(dbName); await browser.scrollToVirtualItem( @@ -142,7 +136,7 @@ describe('Instance databases tab', function () { // the app should stay on the instance Databases tab. await browser.waitUntilActiveConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'Databases' ); }); @@ -152,10 +146,7 @@ describe('Instance databases tab', function () { const dbSelector = Selectors.databaseCard(db); // Browse to the databases tab - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); // Make sure the db card we're going to drop is in there. await browser.scrollToVirtualItem( diff --git a/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts b/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts index bfe1aa54e25..dcf093c0162 100644 --- a/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts @@ -5,8 +5,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -23,7 +22,7 @@ describe('Instance performance tab', function () { await browser.connectWithConnectionString(); await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'Performance' ); }); diff --git a/packages/compass-e2e-tests/tests/instance-sidebar.test.ts b/packages/compass-e2e-tests/tests/instance-sidebar.test.ts index 9ec8159be12..79b0f019d46 100644 --- a/packages/compass-e2e-tests/tests/instance-sidebar.test.ts +++ b/packages/compass-e2e-tests/tests/instance-sidebar.test.ts @@ -8,7 +8,7 @@ import { DEFAULT_CONNECTION_STRING, skipForWeb, TEST_MULTIPLE_CONNECTIONS, - connectionNameFromString, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -19,6 +19,7 @@ const { expect } = chai; describe('Instance sidebar', function () { let compass: Compass; let browser: CompassBrowser; + let connectionId: string | undefined; before(async function () { compass = await init(this.test?.fullTitle()); @@ -28,6 +29,7 @@ describe('Instance sidebar', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); + connectionId = await browser.getConnectionIdByName(DEFAULT_CONNECTION_NAME); }); after(async function () { @@ -41,11 +43,9 @@ describe('Instance sidebar', function () { it('has a connection info modal with connection info', async function () { skipForWeb(this, "these actions don't exist in compass-web"); - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); - if (TEST_MULTIPLE_CONNECTIONS) { await browser.selectConnectionMenuItem( - connectionName, + DEFAULT_CONNECTION_NAME, Selectors.Multiple.ClusterInfoItem ); } else { @@ -65,12 +65,17 @@ describe('Instance sidebar', function () { it('contains a dbs/collections tree view', async function () { const dbName = 'test'; const collectionName = 'numbers'; - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.clickVisible(Selectors.sidebarDatabaseToggle(dbName)); + await browser.clickVisible( + Selectors.sidebarDatabaseToggle(connectionId, dbName) + ); const collectionSelector = Selectors.sidebarCollection( + connectionId, dbName, collectionName ); @@ -113,10 +118,16 @@ describe('Instance sidebar', function () { return treeItems.length === expectedCount; }); - const dbElement = await browser.$(Selectors.sidebarDatabase('test')); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, 'test') + ); expect(await dbElement.isDisplayed()).to.be.true; - const collectionSelector = Selectors.sidebarCollection('test', 'numbers'); + const collectionSelector = Selectors.sidebarCollection( + connectionId, + 'test', + 'numbers' + ); await browser.scrollToVirtualItem( Selectors.SidebarNavigationTree, collectionSelector, @@ -130,7 +141,9 @@ describe('Instance sidebar', function () { // wait for something that didn't match the previous search to show up to make sure that it reset // (otherwise future tests will fail because the new dbs/collections won't match the filter) - const adminElement = await browser.$(Selectors.sidebarDatabase('admin')); + const adminElement = await browser.$( + Selectors.sidebarDatabase(connectionId, 'admin') + ); await adminElement.waitForDisplayed(); }); @@ -142,7 +155,6 @@ describe('Instance sidebar', function () { ? Selectors.Multiple : Selectors.Single; - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); const dbName = `my-sidebar-database-${Date.now()}`; const collectionName = 'my-collection'; @@ -150,14 +162,17 @@ describe('Instance sidebar', function () { // navigate to the databases tab so that the connection is // active/highlighted and then the add button and three dot menu will // display without needing to hover - await browser.navigateToConnectionTab(connectionName, 'Databases'); + await browser.navigateToConnectionTab( + DEFAULT_CONNECTION_NAME, + 'Databases' + ); } // open the create database modal from the sidebar if (TEST_MULTIPLE_CONNECTIONS) { await browser.clickVisible( Selectors.sidebarConnectionActionButton( - connectionName, + DEFAULT_CONNECTION_NAME, Sidebar.CreateDatabaseButton ) ); @@ -174,15 +189,15 @@ describe('Instance sidebar', function () { .$(Selectors.collectionSubTab('Documents', true)) .waitForDisplayed(); - await browser.clickVisible(Selectors.sidebarDatabase(dbName)); + await browser.clickVisible(Selectors.sidebarDatabase(connectionId, dbName)); // wait for it to appear const collectionElement = await browser.$( - Selectors.sidebarCollection(dbName, collectionName) + Selectors.sidebarCollection(connectionId, dbName, collectionName) ); await collectionElement.waitForDisplayed(); - await browser.dropDatabaseFromSidebar(dbName); + await browser.dropDatabaseFromSidebar(DEFAULT_CONNECTION_NAME, dbName); }); it('can create a collection and drop it', async function () { @@ -192,10 +207,12 @@ describe('Instance sidebar', function () { await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); await browser.clickVisible(Selectors.CreateCollectionButton); @@ -207,20 +224,23 @@ describe('Instance sidebar', function () { const tabSelectedSelector = Selectors.collectionSubTab('Documents', true); await browser.$(tabSelectedSelector).waitForDisplayed(); - await browser.dropCollectionFromSidebar(dbName, collectionName); + await browser.dropCollectionFromSidebar( + DEFAULT_CONNECTION_NAME, + dbName, + collectionName + ); }); it('can refresh the databases', async function () { - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); const db = 'test'; const coll = `coll_${Date.now()}`; // expand the database entry in the sidebar - await browser.clickVisible(Selectors.sidebarDatabase(db)); + await browser.clickVisible(Selectors.sidebarDatabase(connectionId, db)); // wait until the collections finish loading const numbersCollectionElement = await browser.$( - Selectors.sidebarCollection(db, 'numbers') + Selectors.sidebarCollection(connectionId, db, 'numbers') ); await numbersCollectionElement.waitForDisplayed(); @@ -235,7 +255,7 @@ describe('Instance sidebar', function () { if (TEST_MULTIPLE_CONNECTIONS) { await browser.selectConnectionMenuItem( - connectionName, + DEFAULT_CONNECTION_NAME, Selectors.Multiple.RefreshDatabasesItem ); } else { @@ -244,7 +264,7 @@ describe('Instance sidebar', function () { // wait for the new collection we added via the driver to appear. const newCollectionElement = await browser.$( - Selectors.sidebarCollection(db, coll) + Selectors.sidebarCollection(connectionId, db, coll) ); await newCollectionElement.waitForDisplayed(); }); diff --git a/packages/compass-e2e-tests/tests/logging.test.ts b/packages/compass-e2e-tests/tests/logging.test.ts index 6e1bb2cfc51..94fd02fc80d 100644 --- a/packages/compass-e2e-tests/tests/logging.test.ts +++ b/packages/compass-e2e-tests/tests/logging.test.ts @@ -5,8 +5,7 @@ import { screenshotIfFailed, skipForWeb, TEST_MULTIPLE_CONNECTIONS, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import { startTelemetryServer } from '../helpers/telemetry'; @@ -20,7 +19,6 @@ describe('Logging and Telemetry integration', function () { describe('after running an example path through Compass', function () { let logs: LogEntry[]; let telemetry: Telemetry; - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); before(async function () { telemetry = await startTelemetryServer(); @@ -35,9 +33,9 @@ describe('Logging and Telemetry integration', function () { await browser.navigateToMyQueries(); } - await browser.shellEval(connectionName, 'use test'); + await browser.shellEval(DEFAULT_CONNECTION_NAME, 'use test'); await browser.shellEval( - connectionName, + DEFAULT_CONNECTION_NAME, 'db.runCommand({ connectionStatus: 1 })' ); } finally { diff --git a/packages/compass-e2e-tests/tests/my-queries-tab.test.ts b/packages/compass-e2e-tests/tests/my-queries-tab.test.ts index 8fb39ee6fd7..3e6f912c905 100644 --- a/packages/compass-e2e-tests/tests/my-queries-tab.test.ts +++ b/packages/compass-e2e-tests/tests/my-queries-tab.test.ts @@ -7,9 +7,8 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, TEST_MULTIPLE_CONNECTIONS, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -44,7 +43,6 @@ async function openMenuForQueryItem( describe('My Queries tab', function () { let compass: Compass; let browser: CompassBrowser; - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); before(async function () { skipForWeb(this, 'saved queries not yet available in compass-web'); @@ -72,7 +70,12 @@ describe('My Queries tab', function () { const newFavoriteQueryName = 'my renamed query'; // Run a query - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', `{i: {$gt: 10}}`, { limit: '10', }); @@ -96,10 +99,7 @@ describe('My Queries tab', function () { await browser.clickVisible(Selectors.QueryHistorySaveFavoriteItemButton); await browser.closeWorkspaceTabs(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); await browser.navigateToMyQueries(); // open the menu @@ -148,14 +148,14 @@ describe('My Queries tab', function () { await renameModal.waitForDisplayed({ reverse: true }); // rename the collection associated with the query to force the open item modal - await browser.shellEval(connectionName, 'use test'); + await browser.shellEval(DEFAULT_CONNECTION_NAME, 'use test'); await browser.shellEval( - connectionName, + DEFAULT_CONNECTION_NAME, 'db.numbers.renameCollection("numbers-renamed")' ); if (TEST_MULTIPLE_CONNECTIONS) { await browser.selectConnectionMenuItem( - connectionName, + DEFAULT_CONNECTION_NAME, Selectors.Multiple.RefreshDatabasesItem ); @@ -195,10 +195,7 @@ describe('My Queries tab', function () { // back to my queries await browser.closeWorkspaceTabs(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); await browser.navigateToMyQueries(); // open the menu @@ -224,7 +221,12 @@ describe('My Queries tab', function () { 'list of numbers greater than 10 - aggregation'; // Navigate to aggregation - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); // add stage await browser.clickVisible(Selectors.AddStageButton); await browser.$(Selectors.stageEditor(0)).waitForDisplayed(); @@ -279,7 +281,12 @@ describe('My Queries tab', function () { // save a query and rename the collection associated with the query, so that the query must be opened with the "select namespace" modal // Run a query - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', `{i: {$gt: 10}}`, { limit: '10', }); @@ -306,7 +313,7 @@ describe('My Queries tab', function () { await browser.closeWorkspaceTabs(); await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'Databases' ); await browser.navigateToMyQueries(); @@ -336,15 +343,15 @@ describe('My Queries tab', function () { } // rename the collection associated with the query to force the open item modal - await browser.shellEval(connectionName, 'use test'); + await browser.shellEval(DEFAULT_CONNECTION_NAME, 'use test'); await browser.shellEval( - connectionName, + DEFAULT_CONNECTION_NAME, `db.numbers.renameCollection('${newCollectionName}')` ); if (TEST_MULTIPLE_CONNECTIONS) { await browser.selectConnectionMenuItem( - connectionName, + DEFAULT_CONNECTION_NAME, Selectors.Multiple.RefreshDatabasesItem ); } else { diff --git a/packages/compass-e2e-tests/tests/read-only.test.ts b/packages/compass-e2e-tests/tests/read-only.test.ts index d1ab6da03dc..2182dd56c46 100644 --- a/packages/compass-e2e-tests/tests/read-only.test.ts +++ b/packages/compass-e2e-tests/tests/read-only.test.ts @@ -4,8 +4,7 @@ import { screenshotIfFailed, skipForWeb, TEST_MULTIPLE_CONNECTIONS, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import { expect } from 'chai'; import * as Selectors from '../helpers/selectors'; @@ -43,18 +42,19 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.setFeature('readOnly', true); await browser.connectWithConnectionString(); - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); - if (TEST_MULTIPLE_CONNECTIONS) { // navigate to the databases tab so that the connection is // active/highlighted and then the add button and three dot menu will // display without needing to hover - await browser.navigateToConnectionTab(connectionName, 'Databases'); + await browser.navigateToConnectionTab( + DEFAULT_CONNECTION_NAME, + 'Databases' + ); } const addDatabaseSelector = TEST_MULTIPLE_CONNECTIONS ? Selectors.sidebarConnectionActionButton( - connectionName, + DEFAULT_CONNECTION_NAME, Sidebar.CreateDatabaseButton ) : Sidebar.CreateDatabaseButton; @@ -75,7 +75,10 @@ describe('readOnly: true / Read-Only Edition', function () { await settingsModal.waitForDisplayed({ reverse: true }); if (TEST_MULTIPLE_CONNECTIONS) { - await browser.navigateToConnectionTab(connectionName, 'Databases'); + await browser.navigateToConnectionTab( + DEFAULT_CONNECTION_NAME, + 'Databases' + ); } expect(await browser.$(addDatabaseSelector).isExisting()).to.be.equal(true); @@ -85,12 +88,18 @@ describe('readOnly: true / Read-Only Edition', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); + const connectionId = await browser.getConnectionIdByName( + DEFAULT_CONNECTION_NAME + ); + const dbName = 'test'; // existing db await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); let sidebarCreateCollectionButton = await browser.$( Selectors.CreateCollectionButton @@ -121,10 +130,7 @@ describe('readOnly: true / Read-Only Edition', function () { it('shows and hides the create database button on the instance tab', async function () { await browser.connectWithConnectionString(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); let instanceCreateDatabaseButton = await browser.$( Selectors.InstanceCreateDatabaseButton @@ -157,7 +163,7 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.connectWithConnectionString(); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -191,7 +197,12 @@ describe('readOnly: true / Read-Only Edition', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); let addDataButton = await browser.$(Selectors.AddDataButton); let isAddDataButtonExisting = await addDataButton.isExisting(); @@ -218,7 +229,12 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.connectWithConnectionString(); // Some tests navigate away from the numbers collection aggregations tab - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); await browser.clickVisible(Selectors.AddStageButton); await browser.$(Selectors.stageEditor(0)).waitForDisplayed(); @@ -266,7 +282,12 @@ describe('readOnly: true / Read-Only Edition', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Indexes' + ); let createIndexButton = await browser.$(Selectors.CreateIndexButton); let isCreateIndexButtonExisting = await createIndexButton.isExisting(); @@ -296,7 +317,12 @@ describe('readOnly: true / Read-Only Edition', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Validation'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Validation' + ); await browser.clickVisible(Selectors.AddRuleButton); const element = await browser.$(Selectors.ValidationEditor); await element.waitForDisplayed(); diff --git a/packages/compass-e2e-tests/tests/search-indexes.test.ts b/packages/compass-e2e-tests/tests/search-indexes.test.ts index 0b854089e3b..b2ca128ea08 100644 --- a/packages/compass-e2e-tests/tests/search-indexes.test.ts +++ b/packages/compass-e2e-tests/tests/search-indexes.test.ts @@ -8,6 +8,7 @@ import { serverSatisfies, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import { expect } from 'chai'; @@ -191,7 +192,12 @@ describe.skip('Search Indexes', function () { } await browser.connectWithConnectionString(currentConnectionString); - await browser.navigateToCollectionTab(DB_NAME, collectionName, 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + DB_NAME, + collectionName, + 'Indexes' + ); }); afterEach(async function () { diff --git a/packages/compass-e2e-tests/tests/shell.test.ts b/packages/compass-e2e-tests/tests/shell.test.ts index 9ae8fae67f5..c4986670ccb 100644 --- a/packages/compass-e2e-tests/tests/shell.test.ts +++ b/packages/compass-e2e-tests/tests/shell.test.ts @@ -7,8 +7,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, TEST_MULTIPLE_CONNECTIONS, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; @@ -43,9 +42,8 @@ describe('Shell', function () { it('has an info modal', async function () { await browser.connectWithConnectionString(); - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); - await browser.openShell(connectionName); + await browser.openShell(DEFAULT_CONNECTION_NAME); await browser.clickVisible(Selectors.ShellInfoButton); const infoModalElement = await browser.$(Selectors.ShellInfoModal); @@ -54,7 +52,7 @@ describe('Shell', function () { await browser.clickVisible(Selectors.ShellInfoModalCloseButton); await infoModalElement.waitForDisplayed({ reverse: true }); - await browser.closeShell(connectionName); + await browser.closeShell(DEFAULT_CONNECTION_NAME); }); it('shows and hides shell based on settings', async function () { diff --git a/packages/compass-e2e-tests/tests/tabs.test.ts b/packages/compass-e2e-tests/tests/tabs.test.ts index 83a5019aa79..53e6aaaa5a1 100644 --- a/packages/compass-e2e-tests/tests/tabs.test.ts +++ b/packages/compass-e2e-tests/tests/tabs.test.ts @@ -1,5 +1,10 @@ import type { CompassBrowser } from '../helpers/compass-browser'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -36,6 +41,7 @@ describe('Global Tabs', function () { it('should open tabs over each other when not modified', async function () { for (const collName of collections) { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', collName, 'Documents', @@ -45,9 +51,10 @@ describe('Global Tabs', function () { expect(await browser.$$(Selectors.workspaceTab())).to.have.lengthOf(1); }); - it('should open tabs over each other when not modified', async function () { + it('should open new tabs when modified', async function () { for (const collName of collections) { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', collName, 'Documents', @@ -64,6 +71,7 @@ describe('Global Tabs', function () { it('should close tabs without warning even when "modified" by interacting with the tab', async function () { for (const collName of collections) { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', collName, 'Documents', @@ -79,7 +87,12 @@ describe('Global Tabs', function () { }); it('should ask for confirmation when closing modified Aggregations tab', async function () { - await browser.navigateToCollectionTab('test', 'a', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'a', + 'Aggregations' + ); await browser.clickVisible( Selectors.aggregationPipelineModeToggle('as-text') diff --git a/packages/compass-e2e-tests/tests/time-to-first-query.test.ts b/packages/compass-e2e-tests/tests/time-to-first-query.test.ts index 38ceffd4ef9..30f4f35284b 100644 --- a/packages/compass-e2e-tests/tests/time-to-first-query.test.ts +++ b/packages/compass-e2e-tests/tests/time-to-first-query.test.ts @@ -1,5 +1,10 @@ import { expect } from 'chai'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -39,7 +44,12 @@ describe('Time to first query', function () { await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', '{ i: 42 }'); @@ -59,7 +69,12 @@ describe('Time to first query', function () { await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', '{ i: 42 }'); diff --git a/packages/compass-sidebar/src/components/use-filtered-connections.ts b/packages/compass-sidebar/src/components/use-filtered-connections.ts index df253640f51..dd583de519a 100644 --- a/packages/compass-sidebar/src/components/use-filtered-connections.ts +++ b/packages/compass-sidebar/src/components/use-filtered-connections.ts @@ -81,11 +81,21 @@ const filterDatabases = ( const childMatches = filterCollections(db.collections, regex); if (isMatch || childMatches.length) { + // If the db doesn't match, we want to use just the matching collections. + // if the db does match we include all the collections but we still record + // if they match because if something does match then we want to expand + // the database in temporarilyExpand below. + const collections = + !isMatch && childMatches.length + ? childMatches + : db.collections.map((collection) => ({ + ...collection, + isMatch: regex.test(collection.name), + })); results.push({ ...db, isMatch, - collections: - !isMatch && childMatches.length ? childMatches : db.collections, + collections, }); } } @@ -129,7 +139,7 @@ const temporarilyExpand = ( } databases.forEach(({ _id: databaseId, collections }) => { const childrenCollsAreMatch = - collections.length && collections[0].isMatch; + collections.length && collections.some((col) => col.isMatch); if (childrenCollsAreMatch && collections.length) { if (newExpanded[connectionId].state === 'collapsed') { newExpanded[connectionId].state = 'tempExpanded';