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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .evergreen/start-atlas-cloud-cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ DELETE_AFTER="$(date -u -Iseconds -d '+2 hours' 2>/dev/null || date -u -Iseconds
#
# - Setup a new org and project. Save the org id and project id for later.
#
# - Add test payment details within the organization (Billing) to be able to
# create clusters.
#
# - Create a new API key (Access Manager > Project Access > Create Application >
# API Key) for the project you created and save the public and private keys.
#
Expand Down Expand Up @@ -104,7 +107,8 @@ echo "Creating Atlas deployment \`$ATLAS_CLUSTER_NAME\` to test against..."
atlascli clusters create $ATLAS_CLUSTER_NAME \
--provider AWS \
--region US_EAST_1 \
--tier M10
--tier M10 \
--type GEOSHARDED

echo "Waiting for the deployment to be provisioned..."
atlascli clusters watch $ATLAS_CLUSTER_NAME
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { CompassBrowser } from '../compass-browser';
import * as Selectors from '../selectors';

export async function clickConfirmationAction(
browser: CompassBrowser,
actionButtonSelector: string,
confirmationText?: string,
screenshot?: string
) {
await browser.clickVisible(actionButtonSelector);

const confirmationModal = await browser.$(Selectors.ConfirmationModal);
await confirmationModal.waitForDisplayed();

if (confirmationText) {
await browser.setValueVisible(
Selectors.ConfirmationModalInput,
confirmationText
);
}

if (screenshot) {
await browser.screenshot(screenshot);
}

await browser.clickVisible(Selectors.confirmationModalConfirmButton());
await confirmationModal.waitForDisplayed({ reverse: true });
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ import type { CompassBrowser } from '../compass-browser';
import * as Selectors from '../selectors';
import type { WorkspaceTabSelectorOptions } from '../selectors';

type CollectionWorkspaceSubTab =
| 'Documents'
| 'Aggregations'
| 'Schema'
| 'Indexes'
| 'Validation'
| 'GlobalWrites';

async function navigateToCollection(
browser: CompassBrowser,
connectionName: string,
Expand Down Expand Up @@ -50,12 +58,8 @@ export async function navigateToCollectionTab(
connectionName: string,
dbName: string,
collectionName: string,
tabName:
| 'Documents'
| 'Aggregations'
| 'Schema'
| 'Indexes'
| 'Validation' = 'Documents',
tabName: CollectionWorkspaceSubTab = 'Documents',

closeExistingTabs = true
): Promise<void> {
await navigateToCollection(
Expand Down Expand Up @@ -83,12 +87,7 @@ export async function navigateToCollectionTab(

export async function navigateWithinCurrentCollectionTabs(
browser: CompassBrowser,
tabName:
| 'Documents'
| 'Aggregations'
| 'Schema'
| 'Indexes'
| 'Validation' = 'Documents'
tabName: CollectionWorkspaceSubTab = 'Documents'
): Promise<void> {
const tab = browser.$(Selectors.collectionSubTab(tabName));
const selectedTab = browser.$(Selectors.collectionSubTab(tabName, true));
Expand All @@ -108,13 +107,7 @@ async function waitUntilActiveCollectionTab(
connectionName: string,
dbName: string,
collectionName: string,
tabName:
| 'Documents'
| 'Aggregations'
| 'Schema'
| 'Indexes'
| 'Validation'
| null = null
tabName: CollectionWorkspaceSubTab | null = null
) {
const options: WorkspaceTabSelectorOptions = {
type: 'Collection',
Expand All @@ -132,12 +125,7 @@ async function waitUntilActiveCollectionTab(

export async function waitUntilActiveCollectionSubTab(
browser: CompassBrowser,
tabName:
| 'Documents'
| 'Aggregations'
| 'Schema'
| 'Indexes'
| 'Validation' = 'Documents'
tabName: CollectionWorkspaceSubTab = 'Documents'
) {
await browser.$(Selectors.collectionSubTab(tabName, true)).waitForDisplayed();
}
Expand Down
18 changes: 4 additions & 14 deletions packages/compass-e2e-tests/helpers/commands/hide-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,11 @@ export async function hideIndex(
await indexComponent.waitForDisplayed();

await browser.hover(indexComponentSelector);
await browser.clickVisible(
`${indexComponentSelector} ${Selectors.HideIndexButton}`
await browser.clickConfirmationAction(
`${indexComponentSelector} ${Selectors.HideIndexButton}`,
undefined,
screenshotName
);

const hideModal = await browser.$(Selectors.ConfirmationModal);
await hideModal.waitForDisplayed();

if (screenshotName) {
await browser.screenshot(screenshotName);
}

await browser.clickVisible(Selectors.confirmationModalConfirmButton());

await hideModal.waitForDisplayed({ reverse: true });

const hiddenBadge = await browser.$(Selectors.HiddenIndexBadge(indexName));
await hiddenBadge.waitForDisplayed();
}
1 change: 1 addition & 0 deletions packages/compass-e2e-tests/helpers/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ export * from './hide-visible-toasts';
export * from './sidebar-collection';
export * from './read-first-document-content';
export * from './read-stage-operators';
export * from './click-confirmation-action';
17 changes: 4 additions & 13 deletions packages/compass-e2e-tests/helpers/commands/unhide-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,12 @@ export async function unhideIndex(
await indexComponent.waitForDisplayed();

await browser.hover(indexComponentSelector);
await browser.clickVisible(
`${indexComponentSelector} ${Selectors.UnhideIndexButton}`
await browser.clickConfirmationAction(
`${indexComponentSelector} ${Selectors.UnhideIndexButton}`,
undefined,
screenshotName
);

const unhideModal = await browser.$(Selectors.ConfirmationModal);
await unhideModal.waitForDisplayed();

if (screenshotName) {
await browser.screenshot(screenshotName);
}

await browser.clickVisible(Selectors.confirmationModalConfirmButton());

await unhideModal.waitForDisplayed({ reverse: true });

const hiddenBadge = await browser.$(Selectors.HiddenIndexBadge(indexName));
await hiddenBadge.waitForDisplayed({ reverse: true });
}
19 changes: 19 additions & 0 deletions packages/compass-e2e-tests/helpers/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1400,3 +1400,22 @@ export const ProxyCustomButton =

// Close tab confirmation
export const ConfirmTabCloseModal = '[data-testid="confirm-tab-close"]';

export const GlobalWrites = {
tabStatus: (status: string) =>
`[data-testid="globalwrites-content"] > [data-status="${status.toLowerCase()}"]`,

ShardKeyFormSecondKeyInputCombobox:
'[data-testid="second-shard-key"] [role="combobox"] input',
ShardKeyFormAdvancedOptionsToggle:
'[data-testid="advanced-shard-key-configuration"]',
shardKeyFormIndexType: (type: 'UNIQUE' | 'HASHED') =>
`[data-testid="${type.toLowerCase()}-index"]`,
ShardKeyFormSubmitButton: '[data-testid="shard-collection-button"]',

CancelShardingButton: '[data-testid="cancel-sharding-btn"]',
UnmanageNamespaceButton: '[data-testid="unmanage-collection-button"]',

SampleFindingDocuments: '[data-testid="sample-finding-documents"]',
SampleInsertingDocuments: '[data-testid="sample-inserting-documents"]',
};
141 changes: 141 additions & 0 deletions packages/compass-e2e-tests/tests/atlas-cloud/global-writes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { expect } from 'chai';
import type { Compass } from '../../helpers/compass';
import { cleanup, init, Selectors } from '../../helpers/compass';
import type { CompassBrowser } from '../../helpers/compass-browser';
import { createGeospatialCollection } from '../../helpers/insert-data';
import {
DEFAULT_CONNECTION_NAMES,
isTestingAtlasCloudSandbox,
} from '../../helpers/test-runner-context';

type GeoShardingFormData = {
secondShardKey: string;
keyType?: 'UNIQUE' | 'HASHED';
};

type GeoShardingStatus = 'UNSHARDED' | 'SHARDING' | 'SHARD_KEY_CORRECT';

async function createGeoShardKey(
browser: CompassBrowser,
formData: GeoShardingFormData
) {
await browser.setComboBoxValue(
Selectors.GlobalWrites.ShardKeyFormSecondKeyInputCombobox,
formData.secondShardKey
);

if (formData.keyType) {
await browser.clickVisible(
Selectors.GlobalWrites.ShardKeyFormAdvancedOptionsToggle
);
await browser.clickParent(
Selectors.GlobalWrites.shardKeyFormIndexType(formData.keyType)
);
}
await browser.clickVisible(Selectors.GlobalWrites.ShardKeyFormSubmitButton);
}

async function waitForGlobalWritesStatus(
browser: CompassBrowser,
nextStatus: GeoShardingStatus
) {
await browser.waitUntil(async () => {
const content = await browser.$(
Selectors.GlobalWrites.tabStatus(nextStatus)
);
return await content.isDisplayed();
});
}

describe('Global writes', function () {
let compass: Compass;
let browser: CompassBrowser;

beforeEach(async function () {
// Sharding a collection takes a bit longer
this.timeout(1000 * 60 * 20);
compass = await init(this.test?.fullTitle());
browser = compass.browser;
await browser.setupDefaultConnections();
});

before(function () {
if (!isTestingAtlasCloudSandbox()) {
this.skip();
}
});

after(async function () {
await cleanup(compass);
});

it('should be able to shard an unsharded namespace and also unmanage it', async function () {
await createGeospatialCollection();
await browser.connectToDefaults();
await browser.navigateToCollectionTab(
DEFAULT_CONNECTION_NAMES[0],
'test',
'geospatial',
'GlobalWrites'
);

// Initial state is loading
await waitForGlobalWritesStatus(browser, 'UNSHARDED');

await createGeoShardKey(browser, {
secondShardKey: 'country',
keyType: 'HASHED',
});

// Wait for the shard key to be correct.
await waitForGlobalWritesStatus(browser, 'SHARD_KEY_CORRECT');

// Expectations to see the shard key in the UI
const findingDocumentsText = await browser
.$(Selectors.GlobalWrites.SampleFindingDocuments)
.getText();

const insertedDocumentsText = await browser
.$(Selectors.GlobalWrites.SampleInsertingDocuments)
.getText();

expect(findingDocumentsText).to.include('country');
expect(insertedDocumentsText).to.include('country');

// Unmanage the namespace
await browser.clickVisible(Selectors.GlobalWrites.UnmanageNamespaceButton);

// It transitions to the unmanaging state
await waitForGlobalWritesStatus(browser, 'UNSHARDED');
Copy link
Collaborator

Choose a reason for hiding this comment

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

note: this will be INCOMPLETE_SHARDING_SETUP after #6399, but it's quite likely that this will be merged first, so I'll update the test afterwards

Copy link
Collaborator

Choose a reason for hiding this comment

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

I might even add a test to check that the form is not present at this point, it's important that the key cannot be changed after unmanaging. But again, this hangs on my PR.

});

it('should be able to shard an unsharded namespace and cancel the operation', async function () {
await createGeospatialCollection();
await browser.connectToDefaults();
await browser.navigateToCollectionTab(
DEFAULT_CONNECTION_NAMES[0],
'test',
'geospatial',
'GlobalWrites'
);

// Initial state is loading
await waitForGlobalWritesStatus(browser, 'UNSHARDED');

await createGeoShardKey(browser, {
secondShardKey: 'country',
keyType: 'UNIQUE',
});

// Wait for the shard key to be correct.
await waitForGlobalWritesStatus(browser, 'SHARDING');

// Cancel the sharding operation.
await browser.clickConfirmationAction(
Selectors.GlobalWrites.CancelShardingButton
);

// After its cancelled, it should transition back to the unsharded state
await waitForGlobalWritesStatus(browser, 'UNSHARDED');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -1011,13 +1011,7 @@ describe('Collection aggregations tab', function () {

it('shows confirmation modal when create new pipeline is clicked and aggregation is modified', async function () {
await browser.selectStageOperator(0, '$match');

await browser.clickVisible(Selectors.CreateNewPipelineButton);
const modalElement = await browser.$(Selectors.ConfirmationModal);
await modalElement.waitForDisplayed();

await browser.clickVisible(Selectors.confirmationModalConfirmButton());
await modalElement.waitForDisplayed({ reverse: true });
await browser.clickConfirmationAction(Selectors.CreateNewPipelineButton);
});

describe('aggregation builder in text mode', function () {
Expand Down Expand Up @@ -1258,14 +1252,9 @@ describe('Collection aggregations tab', function () {
);
await browser.hover(Selectors.AggregationSavedPipelineCard(name));

await browser.clickVisible(
await browser.clickConfirmationAction(
Selectors.AggregationSavedPipelineCardOpenButton(name)
);

const confirmOpenModal = await browser.$(Selectors.ConfirmationModal);
await confirmOpenModal.waitForDisplayed();
await browser.clickVisible(Selectors.confirmationModalConfirmButton());
await confirmOpenModal.waitForDisplayed({ reverse: true });
});

it('deletes an aggregation', async function () {
Expand All @@ -1278,14 +1267,9 @@ describe('Collection aggregations tab', function () {
);
await browser.hover(Selectors.AggregationSavedPipelineCard(name));

await browser.clickVisible(
await browser.clickConfirmationAction(
Selectors.AggregationSavedPipelineCardDeleteButton(name)
);

const confirmDeleteModal = await browser.$(Selectors.ConfirmationModal);
await confirmDeleteModal.waitForDisplayed();
await browser.clickVisible(Selectors.confirmationModalConfirmButton());
await confirmDeleteModal.waitForDisplayed({ reverse: true });
});
});

Expand Down
Loading
Loading