Skip to content

Commit 073dcea

Browse files
paula-stachoAnemy
andauthored
test: add data-modeling tab e2e test COMPASS-9305 (#6885)
Co-authored-by: Rhys <[email protected]>
1 parent 0c31b63 commit 073dcea

File tree

6 files changed

+221
-4
lines changed

6 files changed

+221
-4
lines changed

packages/compass-data-modeling/src/components/diagram-editor.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,16 +159,19 @@ const DiagramEditor: React.FunctionComponent<{
159159

160160
if (step === 'EDITING') {
161161
content = (
162-
<div className={modelPreviewContainerStyles}>
163-
<div className={modelPreviewStyles}>
162+
<div
163+
className={modelPreviewContainerStyles}
164+
data-testid="diagram-editor-container"
165+
>
166+
<div className={modelPreviewStyles} data-testid="model-preview">
164167
<CodemirrorMultilineEditor
165168
language="json"
166169
text={modelStr}
167170
readOnly
168171
initialJSONFoldAll={false}
169172
></CodemirrorMultilineEditor>
170173
</div>
171-
<div className={editorContainerStyles}>
174+
<div className={editorContainerStyles} data-testid="apply-editor">
172175
<div>
173176
<CodemirrorMultilineEditor
174177
language="json"
@@ -182,6 +185,7 @@ const DiagramEditor: React.FunctionComponent<{
182185
onClick={() => {
183186
onApplyClick(JSON.parse(applyInput));
184187
}}
188+
data-testid="apply-button"
185189
disabled={!isEditValid}
186190
>
187191
Apply

packages/compass-data-modeling/src/components/new-diagram-form.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const FormStepContainer: React.FunctionComponent<{
6161
onClick={onNextClick}
6262
disabled={isNextDisabled}
6363
isLoading={isLoading}
64+
data-testid="new-diagram-confirm-button"
6465
variant="primary"
6566
>
6667
{nextLabel}
@@ -202,6 +203,7 @@ const NewDiagramForm: React.FunctionComponent<NewDiagramFormProps> = ({
202203
<TextInput
203204
label="New data model name"
204205
value={diagramName}
206+
data-testId="new-diagram-name-input"
205207
onChange={(e) => {
206208
onNameChange(e.currentTarget.value);
207209
}}
@@ -214,6 +216,7 @@ const NewDiagramForm: React.FunctionComponent<NewDiagramFormProps> = ({
214216
<Select
215217
label=""
216218
value={selectedConnectionId ?? ''}
219+
data-testid="new-diagram-connection-selector"
217220
onChange={onConnectionSelect}
218221
disabled={connections.length === 0}
219222
>
@@ -238,6 +241,7 @@ const NewDiagramForm: React.FunctionComponent<NewDiagramFormProps> = ({
238241
<Select
239242
label=""
240243
value={selectedDatabase ?? ''}
244+
data-testid="new-diagram-database-selector"
241245
onChange={onDatabaseSelect}
242246
>
243247
{databases.map((db) => {
@@ -259,6 +263,7 @@ const NewDiagramForm: React.FunctionComponent<NewDiagramFormProps> = ({
259263
return {
260264
id: collName,
261265
selected: selectedCollections.includes(collName),
266+
'data-testid': `new-diagram-collection-checkbox-${collName}`,
262267
};
263268
})}
264269
columns={[['id', 'Collection Name']]}
@@ -294,6 +299,7 @@ const NewDiagramForm: React.FunctionComponent<NewDiagramFormProps> = ({
294299
return (
295300
<Modal
296301
open={isModalOpen}
302+
data-testid="new-diagram-modal"
297303
setOpen={(open) => {
298304
if (!open) {
299305
onCancel();

packages/compass-data-modeling/src/components/saved-diagrams-list.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ const SavedDiagramsList: React.FunctionComponent<{
4545
onClick={() => {
4646
onOpenDiagramClick(diagram);
4747
}}
48+
data-testid="saved-diagram-card"
49+
data-diagram-name={diagram.name}
4850
>
4951
{diagram.name}
5052
<ItemActionMenu
@@ -81,7 +83,11 @@ const SavedDiagramsList: React.FunctionComponent<{
8183
</>
8284
}
8385
callToAction={
84-
<Button onClick={onCreateDiagramClick} variant="primary">
86+
<Button
87+
onClick={onCreateDiagramClick}
88+
variant="primary"
89+
data-testid="create-diagram-button"
90+
>
8591
Create diagram
8692
</Button>
8793
}
@@ -98,6 +104,7 @@ const SavedDiagramsList: React.FunctionComponent<{
98104
onClick={onCreateDiagramClick}
99105
variant="primary"
100106
size="xsmall"
107+
data-testid="create-diagram-button"
101108
>
102109
Create diagram
103110
</Button>

packages/compass-e2e-tests/helpers/commands/workspace-tabs.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Key } from 'webdriverio';
12
import type { CompassBrowser } from '../compass-browser';
23
import * as Selectors from '../selectors';
34
import type { WorkspaceTabSelectorOptions } from '../selectors';
@@ -11,6 +12,13 @@ export async function navigateToMyQueries(browser: CompassBrowser) {
1112
.waitForDisplayed();
1213
}
1314

15+
export async function navigateToDataModeling(browser: CompassBrowser) {
16+
await browser.clickVisible(Selectors.SidebarDataModelingTab);
17+
await browser
18+
.$(Selectors.workspaceTab({ type: 'Data Modeling', active: true }))
19+
.waitForDisplayed();
20+
}
21+
1422
async function closeTab(
1523
browser: CompassBrowser,
1624
selectorOptions: WorkspaceTabSelectorOptions,
@@ -87,3 +95,15 @@ export async function closeWorkspaceTab(
8795
): Promise<void> {
8896
await closeTab(browser, selectorOptions, true);
8997
}
98+
99+
export async function openNewTab(browser: CompassBrowser): Promise<void> {
100+
const countTabs = async () => {
101+
return await browser.$$(Selectors.workspaceTab()).length;
102+
};
103+
const tabsBefore = await countTabs();
104+
await browser.keys([Key.Ctrl, 't']);
105+
await browser.waitUntil(async () => {
106+
const tabsAfter = await countTabs();
107+
return tabsAfter === tabsBefore + 1;
108+
});
109+
}

packages/compass-e2e-tests/helpers/selectors.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,3 +1426,27 @@ export const AutoUpdateDownloadLink =
14261426
'[data-testid="auto-update-download-link"]';
14271427
export const AutoUpdateReleaseNotesLink =
14281428
'[data-testid="auto-update-release-notes-link"]';
1429+
1430+
// Data Modeling
1431+
export const SidebarDataModelingTab = `${Sidebar} [aria-label="Data Modeling"]`;
1432+
export const CreateNewDataModelButton = '[data-testid="create-diagram-button"]';
1433+
export const CreateDataModelModal = '[data-testid="new-diagram-modal"]';
1434+
export const CreateDataModelConfirmButton = `${CreateDataModelModal} [data-testid="new-diagram-confirm-button"]`;
1435+
export const CreateDataModelNameInput = `${CreateDataModelModal} [data-testid="new-diagram-name-input"]`;
1436+
export const CreateDataModelConnectionSelector = `${CreateDataModelModal} [data-testid="new-diagram-connection-selector"]`;
1437+
export const CreateDataModelDatabaseSelector = `${CreateDataModelModal} [data-testid="new-diagram-database-selector"]`;
1438+
export const CreateDataModelCollectionCheckbox = (
1439+
collectionName: string
1440+
): string =>
1441+
`${CreateDataModelModal} [data-testid="new-diagram-collection-checkbox-${collectionName}"]`;
1442+
export const DataModelEditor = '[data-testid="diagram-editor-container"]';
1443+
export const DataModelPreview = `${DataModelEditor} [data-testid="model-preview"]`;
1444+
export const DataModelApplyEditor = `${DataModelEditor} [data-testid="apply-editor"]`;
1445+
export const DataModelEditorApplyButton = `${DataModelApplyEditor} [data-testid="apply-button"]`;
1446+
export const DataModelUndoButton = 'button[aria-label="Undo"]';
1447+
export const DataModelRedoButton = 'button[aria-label="Redo"]';
1448+
export const DataModelsListItem = (diagramName: string) =>
1449+
`[data-testid="saved-diagram-card"][data-diagram-name="${diagramName}"]`;
1450+
export const DataModelsListItemActions = (diagramName: string) =>
1451+
`${DataModelsListItem(diagramName)} [aria-label="Show actions"]`;
1452+
export const DataModelsListItemDeleteButton = `[data-action="delete"]`;
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import { expect } from 'chai';
2+
import type { CompassBrowser } from '../helpers/compass-browser';
3+
import {
4+
init,
5+
cleanup,
6+
screenshotIfFailed,
7+
skipForWeb,
8+
DEFAULT_CONNECTION_NAME_1,
9+
} from '../helpers/compass';
10+
import type { Compass } from '../helpers/compass';
11+
import * as Selectors from '../helpers/selectors';
12+
import {
13+
createNestedDocumentsCollection,
14+
createNumbersCollection,
15+
} from '../helpers/insert-data';
16+
17+
describe('Data Modeling tab', function () {
18+
let compass: Compass;
19+
let browser: CompassBrowser;
20+
21+
before(async function () {
22+
skipForWeb(this, 'data modeling not yet available in compass-web');
23+
24+
compass = await init(this.test?.fullTitle());
25+
browser = compass.browser;
26+
await browser.setFeature('enableDataModeling', true);
27+
await browser.setupDefaultConnections();
28+
});
29+
30+
beforeEach(async function () {
31+
await createNestedDocumentsCollection('testCollection1');
32+
await createNumbersCollection('testCollection2');
33+
await browser.disconnectAll();
34+
await browser.connectToDefaults();
35+
});
36+
37+
after(async function () {
38+
if (compass) {
39+
await cleanup(compass);
40+
}
41+
});
42+
43+
afterEach(async function () {
44+
await screenshotIfFailed(compass, this.currentTest);
45+
});
46+
47+
it('creates a new data model using an existing connection', async function () {
48+
await browser.navigateToDataModeling();
49+
50+
// Click on create new data model button
51+
await browser.clickVisible(Selectors.CreateNewDataModelButton);
52+
53+
// Fill in model details
54+
const dataModelName = 'Test Data Model';
55+
await browser.setValueVisible(
56+
Selectors.CreateDataModelNameInput,
57+
dataModelName
58+
);
59+
await browser.clickVisible(Selectors.CreateDataModelConfirmButton);
60+
61+
// Select existing connection
62+
await browser.selectOption(
63+
Selectors.CreateDataModelConnectionSelector,
64+
DEFAULT_CONNECTION_NAME_1
65+
);
66+
await browser.clickVisible(Selectors.CreateDataModelConfirmButton);
67+
68+
// Select a database
69+
await browser.selectOption(
70+
Selectors.CreateDataModelDatabaseSelector,
71+
'test'
72+
);
73+
await browser.clickVisible(Selectors.CreateDataModelConfirmButton);
74+
75+
// TODO: Confirm all collections are selected by default (COMPASS-9309)
76+
// Note: We'll need to change the UI, right now the labels are disconnected from the checkboxes
77+
await browser.clickVisible(Selectors.CreateDataModelConfirmButton);
78+
79+
// Wait for the diagram editor to load
80+
const dataModelEditor = browser.$(Selectors.DataModelEditor);
81+
await dataModelEditor.waitForDisplayed();
82+
83+
// Verify that the diagram is displayed and contains both collections
84+
const text = await browser.getCodemirrorEditorText(
85+
Selectors.DataModelPreview
86+
);
87+
expect(text).to.include('"test.testCollection1": ');
88+
expect(text).to.include('"test.testCollection2": ');
89+
90+
// Apply change to the model
91+
const newModel = {
92+
type: 'SetModel',
93+
model: { schema: { coll1: {}, coll2: {} } },
94+
};
95+
const newPreview = JSON.stringify(newModel.model, null, 2);
96+
await browser.setCodemirrorEditorValue(
97+
Selectors.DataModelApplyEditor,
98+
JSON.stringify(newModel)
99+
);
100+
await browser.clickVisible(Selectors.DataModelEditorApplyButton);
101+
102+
// Verify that the model is updated
103+
const updatedText = await browser.getCodemirrorEditorText(
104+
Selectors.DataModelPreview
105+
);
106+
expect(updatedText).to.equal(newPreview);
107+
108+
// Undo the change
109+
await browser.clickVisible(Selectors.DataModelUndoButton);
110+
await browser.waitUntil(async () => {
111+
const textAfterUndo = await browser.getCodemirrorEditorText(
112+
Selectors.DataModelPreview
113+
);
114+
return (
115+
textAfterUndo.includes('"test.testCollection1": ') &&
116+
textAfterUndo.includes('"test.testCollection2": ')
117+
);
118+
});
119+
120+
// Redo the change
121+
await browser.waitForAriaDisabled(Selectors.DataModelRedoButton, false);
122+
await browser.clickVisible(Selectors.DataModelRedoButton);
123+
await browser.waitUntil(async () => {
124+
const redoneText = await browser.getCodemirrorEditorText(
125+
Selectors.DataModelPreview
126+
);
127+
return redoneText === newPreview;
128+
});
129+
130+
// Open a new tab
131+
await browser.openNewTab();
132+
133+
// Open the saved diagram
134+
await browser.clickVisible(Selectors.DataModelsListItem(dataModelName));
135+
await browser.$(Selectors.DataModelEditor).waitForDisplayed();
136+
137+
// Verify that the diagram has the latest changes
138+
const savedText = await browser.getCodemirrorEditorText(
139+
Selectors.DataModelPreview
140+
);
141+
expect(savedText).to.equal(newPreview);
142+
143+
// Open a new tab
144+
await browser.openNewTab();
145+
146+
// Delete the saved diagram
147+
await browser.clickVisible(
148+
Selectors.DataModelsListItemActions(dataModelName)
149+
);
150+
await browser.clickVisible(Selectors.DataModelsListItemDeleteButton);
151+
await browser.clickVisible(Selectors.confirmationModalConfirmButton());
152+
await browser
153+
.$(Selectors.DataModelsListItem(dataModelName))
154+
.waitForDisplayed({ reverse: true });
155+
});
156+
});

0 commit comments

Comments
 (0)