From 1bc9202b47feae2450ed26c2e37ddf6b08a83ca9 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Mon, 4 Mar 2024 11:06:25 +0000 Subject: [PATCH 1/8] lots more waiting and checks between actions in the flaky test --- .../compass-e2e-tests/helpers/selectors.ts | 1 + .../tests/instance-databases-tab.test.ts | 45 +++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/packages/compass-e2e-tests/helpers/selectors.ts b/packages/compass-e2e-tests/helpers/selectors.ts index ddb74e16307..180293e6dd8 100644 --- a/packages/compass-e2e-tests/helpers/selectors.ts +++ b/packages/compass-e2e-tests/helpers/selectors.ts @@ -400,6 +400,7 @@ export const DatabaseCard = '[data-testid="database-grid-item"]'; export const DatabaseCardDrop = '[data-testid="database-grid"] [data-testid="namespace-card-actions"] button'; export const ServerStats = '.serverstats'; +export const DatabaseStatLoader = `${DatabaseCard} [data-testid="placeholder"]`; export const databaseCard = (dbName: string): string => { return `${DatabaseCard}[data-id="${dbName}"]`; 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 12608eb235d..c62ca9642da 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -14,6 +14,8 @@ import { createNumbersCollection, } from '../helpers/insert-data'; +const INITIAL_DATABASE_NAMES = ['admin', 'config', 'local', 'test']; + describe('Instance databases tab', function () { let compass: Compass; let browser: CompassBrowser; @@ -42,9 +44,7 @@ describe('Instance databases tab', function () { const dbTable = await browser.$(Selectors.DatabasesTable); await dbTable.waitForDisplayed(); - const dbSelectors = ['admin', 'config', 'local', 'test'].map( - Selectors.databaseCard - ); + const dbSelectors = INITIAL_DATABASE_NAMES.map(Selectors.databaseCard); for (const dbSelector of dbSelectors) { const found = await browser.scrollToVirtualItem( @@ -138,10 +138,37 @@ describe('Instance databases tab', function () { }); it('can refresh the list of databases using refresh controls', async function () { + await browser.navigateToInstanceTab('Databases'); + + // Wait for the cards to appear to make sure it started loading + const dbSelectors = INITIAL_DATABASE_NAMES.map(Selectors.databaseCard); + + for (const dbSelector of dbSelectors) { + const found = await browser.scrollToVirtualItem( + Selectors.DatabasesTable, + dbSelector, + 'grid' + ); + expect(found, dbSelector).to.be.true; + } + + // Wait for the page to finish loading + await browser.waitUntil(async () => { + return (await browser.$$(Selectors.DatabaseStatLoader)).length === 0; + }); + const db = 'my-instance-database'; const coll = 'my-collection'; const dbSelector = Selectors.databaseCard(db); + // Make very sure the database doesn't already exist + const found = await browser.scrollToVirtualItem( + Selectors.DatabasesTable, + dbSelector, + 'grid' + ); + expect(found, dbSelector).to.be.false; + // Create the database and refresh const mongoClient = new MongoClient(DEFAULT_CONNECTION_STRING); await mongoClient.connect(); @@ -149,9 +176,9 @@ describe('Instance databases tab', function () { const database = mongoClient.db(db); await database.createCollection(coll); - await browser.navigateToInstanceTab('Databases'); await browser.clickVisible(Selectors.InstanceRefreshDatabaseButton); + // The new database card should appear await browser.scrollToVirtualItem( Selectors.DatabasesTable, dbSelector, @@ -159,10 +186,14 @@ describe('Instance databases tab', function () { ); await browser.$(dbSelector).waitForDisplayed(); - // Drop it and refresh again + // TODO(COMPASS-7695): wait for the skeleton loaders to go away to signal + // that it is done refreshing. + + // Drop it console.log({ 'database.dropDatabase()': await database.dropDatabase(), }); + // Prove that it is really gone console.log({ 'database.admin().listDatabases()': ( await database.admin().listDatabases() @@ -172,9 +203,7 @@ describe('Instance databases tab', function () { await mongoClient.close(); } - // looks like if you refresh too fast the database appears in the list but - // the stats never load, so just pause for bit first - await browser.pause(1000); + // Refresh again and the database card should disappear. await browser.clickVisible(Selectors.InstanceRefreshDatabaseButton); await browser.$(dbSelector).waitForExist({ reverse: true }); }); From 94f30131693b6a60e9dc94108d9cc9a72e7881c5 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Wed, 6 Mar 2024 09:54:06 +0000 Subject: [PATCH 2/8] WIP --- packages/instance-model/lib/model.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/instance-model/lib/model.js b/packages/instance-model/lib/model.js index ede3ab1c0cc..f7da88dbf8a 100644 --- a/packages/instance-model/lib/model.js +++ b/packages/instance-model/lib/model.js @@ -225,15 +225,18 @@ const InstanceModel = AmpersandModel.extend( if (!shouldFetch(this.status, force)) { return; } + console.log('instance fetch'); try { const newStatus = this.status === 'initial' ? 'fetching' : 'refreshing'; this.set({ status: newStatus }); const instanceInfo = await dataService.instance(); this.set({ status: 'ready', statusError: null, ...instanceInfo }); } catch (err) { + console.log('instance fetch error'); this.set({ status: 'error', statusError: err.message }); throw err; } + console.log('instance fetch success'); }, /** @@ -245,18 +248,21 @@ const InstanceModel = AmpersandModel.extend( return; } try { + console.log('instance fetchDatabases'); const newStatus = this.databasesStatus === 'initial' ? 'fetching' : 'refreshing'; this.set({ databasesStatus: newStatus }); await this.databases.fetch({ dataService }); this.set({ databasesStatus: 'ready', databasesStatusError: null }); } catch (err) { + console.log('instance fetchingDatabases error', err); this.set({ databasesStatus: 'error', databasesStatusError: err.message, }); throw err; } + console.log('instance fetchingDatabases success'); }, /** @@ -285,6 +291,7 @@ const InstanceModel = AmpersandModel.extend( fetchCollections = false, fetchCollStats = false, }) { + console.log('instance refresh'); this.set({ refreshingStatus: this.refreshingStatus === 'initial' ? 'fetching' : 'refreshing', @@ -339,12 +346,15 @@ const InstanceModel = AmpersandModel.extend( this.set({ refreshingStatus: 'ready', refreshingStatusError: null }); } catch (err) { + console.log('instance refresh error'); this.set({ refreshingStatus: 'error', refreshingStatusError: err.message, }); throw err; } + + console.log('instance refresh success'); }, async getNamespace({ dataService, database, collection }) { From b1c0f24cba4b20934ee4db0e8a21e9e7842561ac Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Wed, 6 Mar 2024 10:14:54 +0000 Subject: [PATCH 3/8] remove the console.log lines again --- packages/instance-model/lib/model.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/instance-model/lib/model.js b/packages/instance-model/lib/model.js index f7da88dbf8a..ede3ab1c0cc 100644 --- a/packages/instance-model/lib/model.js +++ b/packages/instance-model/lib/model.js @@ -225,18 +225,15 @@ const InstanceModel = AmpersandModel.extend( if (!shouldFetch(this.status, force)) { return; } - console.log('instance fetch'); try { const newStatus = this.status === 'initial' ? 'fetching' : 'refreshing'; this.set({ status: newStatus }); const instanceInfo = await dataService.instance(); this.set({ status: 'ready', statusError: null, ...instanceInfo }); } catch (err) { - console.log('instance fetch error'); this.set({ status: 'error', statusError: err.message }); throw err; } - console.log('instance fetch success'); }, /** @@ -248,21 +245,18 @@ const InstanceModel = AmpersandModel.extend( return; } try { - console.log('instance fetchDatabases'); const newStatus = this.databasesStatus === 'initial' ? 'fetching' : 'refreshing'; this.set({ databasesStatus: newStatus }); await this.databases.fetch({ dataService }); this.set({ databasesStatus: 'ready', databasesStatusError: null }); } catch (err) { - console.log('instance fetchingDatabases error', err); this.set({ databasesStatus: 'error', databasesStatusError: err.message, }); throw err; } - console.log('instance fetchingDatabases success'); }, /** @@ -291,7 +285,6 @@ const InstanceModel = AmpersandModel.extend( fetchCollections = false, fetchCollStats = false, }) { - console.log('instance refresh'); this.set({ refreshingStatus: this.refreshingStatus === 'initial' ? 'fetching' : 'refreshing', @@ -346,15 +339,12 @@ const InstanceModel = AmpersandModel.extend( this.set({ refreshingStatus: 'ready', refreshingStatusError: null }); } catch (err) { - console.log('instance refresh error'); this.set({ refreshingStatus: 'error', refreshingStatusError: err.message, }); throw err; } - - console.log('instance refresh success'); }, async getNamespace({ dataService, database, collection }) { From f8f7efd11de4fb53ea4bc4127a80943e77aaa64e Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Wed, 6 Mar 2024 10:34:57 +0000 Subject: [PATCH 4/8] rewrite the test --- .../compass-e2e-tests/helpers/selectors.ts | 2 +- .../tests/instance-databases-tab.test.ts | 51 ++++--------------- .../src/namespace-param.tsx | 2 + 3 files changed, 13 insertions(+), 42 deletions(-) diff --git a/packages/compass-e2e-tests/helpers/selectors.ts b/packages/compass-e2e-tests/helpers/selectors.ts index 180293e6dd8..cb236703bba 100644 --- a/packages/compass-e2e-tests/helpers/selectors.ts +++ b/packages/compass-e2e-tests/helpers/selectors.ts @@ -400,7 +400,7 @@ export const DatabaseCard = '[data-testid="database-grid-item"]'; export const DatabaseCardDrop = '[data-testid="database-grid"] [data-testid="namespace-card-actions"] button'; export const ServerStats = '.serverstats'; -export const DatabaseStatLoader = `${DatabaseCard} [data-testid="placeholder"]`; +export const DatabaseStatLoader = `${DatabaseCard} [data-testid="namespace-param-fallback"][data-ready=false]`; export const databaseCard = (dbName: string): string => { return `${DatabaseCard}[data-id="${dbName}"]`; 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 c62ca9642da..10a18b04224 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -138,58 +138,27 @@ describe('Instance databases tab', function () { }); it('can refresh the list of databases using refresh controls', async function () { - await browser.navigateToInstanceTab('Databases'); - - // Wait for the cards to appear to make sure it started loading - const dbSelectors = INITIAL_DATABASE_NAMES.map(Selectors.databaseCard); - - for (const dbSelector of dbSelectors) { - const found = await browser.scrollToVirtualItem( - Selectors.DatabasesTable, - dbSelector, - 'grid' - ); - expect(found, dbSelector).to.be.true; - } - - // Wait for the page to finish loading - await browser.waitUntil(async () => { - return (await browser.$$(Selectors.DatabaseStatLoader)).length === 0; - }); - const db = 'my-instance-database'; const coll = 'my-collection'; const dbSelector = Selectors.databaseCard(db); - // Make very sure the database doesn't already exist - const found = await browser.scrollToVirtualItem( - Selectors.DatabasesTable, - dbSelector, - 'grid' - ); - expect(found, dbSelector).to.be.false; - - // Create the database and refresh const mongoClient = new MongoClient(DEFAULT_CONNECTION_STRING); await mongoClient.connect(); try { + // Create the database before browsing to the databases tab to minimize + // how many times we have to refresh const database = mongoClient.db(db); await database.createCollection(coll); - await browser.clickVisible(Selectors.InstanceRefreshDatabaseButton); - - // The new database card should appear - await browser.scrollToVirtualItem( - Selectors.DatabasesTable, - dbSelector, - 'grid' - ); - await browser.$(dbSelector).waitForDisplayed(); - - // TODO(COMPASS-7695): wait for the skeleton loaders to go away to signal - // that it is done refreshing. + // Browse to the databases tab and wait for the page to finish loading + await browser.navigateToInstanceTab('Databases'); + await browser.waitUntil(async () => { + const placeholders = await browser.$$(Selectors.DatabaseStatLoader); + console.log(placeholders); + return placeholders.length === 0; + }); - // Drop it + // Drop the database console.log({ 'database.dropDatabase()': await database.dropDatabase(), }); diff --git a/packages/databases-collections-list/src/namespace-param.tsx b/packages/databases-collections-list/src/namespace-param.tsx index 4d3cd3b33d4..844fd47e96d 100644 --- a/packages/databases-collections-list/src/namespace-param.tsx +++ b/packages/databases-collections-list/src/namespace-param.tsx @@ -127,6 +127,8 @@ export const NamespaceParam: React.FunctionComponent<{ }} fallback={(shouldRender) => ( Date: Wed, 6 Mar 2024 14:13:37 +0000 Subject: [PATCH 5/8] don't add something while the initial load is ongoing --- .../tests/instance-databases-tab.test.ts | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) 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 10a18b04224..64f2dcd3225 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -138,25 +138,29 @@ describe('Instance databases tab', function () { }); it('can refresh the list of databases using refresh controls', async function () { - const db = 'my-instance-database'; - const coll = 'my-collection'; + const db = 'test'; // added by beforeEach const dbSelector = Selectors.databaseCard(db); + // Browse to the databases tab and wait for the page to finish loading + await browser.navigateToInstanceTab('Databases'); + await browser.waitUntil(async () => { + const placeholders = await browser.$$(Selectors.DatabaseStatLoader); + return placeholders.length === 0; + }); + + // Make sure the db card we're going to drop is in there. + await browser.scrollToVirtualItem( + Selectors.DatabasesTable, + dbSelector, + 'grid' + ); + await browser.$(dbSelector).waitForDisplayed(); + + // Drop the database using hte driver const mongoClient = new MongoClient(DEFAULT_CONNECTION_STRING); await mongoClient.connect(); try { - // Create the database before browsing to the databases tab to minimize - // how many times we have to refresh const database = mongoClient.db(db); - await database.createCollection(coll); - - // Browse to the databases tab and wait for the page to finish loading - await browser.navigateToInstanceTab('Databases'); - await browser.waitUntil(async () => { - const placeholders = await browser.$$(Selectors.DatabaseStatLoader); - console.log(placeholders); - return placeholders.length === 0; - }); // Drop the database console.log({ From 69fd20203f173253a6e6cd21aee0af640ed5bc84 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Wed, 6 Mar 2024 15:41:35 +0000 Subject: [PATCH 6/8] scroll and take a screenshot before click --- .../compass-e2e-tests/tests/instance-databases-tab.test.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 64f2dcd3225..fd646f3301d 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -137,7 +137,7 @@ describe('Instance databases tab', function () { await browser.waitUntilActiveInstanceTab('Databases'); }); - it('can refresh the list of databases using refresh controls', async function () { + it.only('can refresh the list of databases using refresh controls', async function () { const db = 'test'; // added by beforeEach const dbSelector = Selectors.databaseCard(db); @@ -177,7 +177,10 @@ describe('Instance databases tab', function () { } // Refresh again and the database card should disappear. - await browser.clickVisible(Selectors.InstanceRefreshDatabaseButton); + await browser.clickVisible(Selectors.InstanceRefreshDatabaseButton, { + scroll: true, + screenshot: 'instance-refresh-database-button.png', + }); await browser.$(dbSelector).waitForExist({ reverse: true }); }); }); From 135369258084740e9bf04fa621d67f37a64dc165 Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Wed, 6 Mar 2024 15:43:09 +0000 Subject: [PATCH 7/8] slight tweak --- .../tests/instance-databases-tab.test.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) 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 fd646f3301d..1ca27fc4319 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -141,12 +141,8 @@ describe('Instance databases tab', function () { const db = 'test'; // added by beforeEach const dbSelector = Selectors.databaseCard(db); - // Browse to the databases tab and wait for the page to finish loading + // Browse to the databases tab await browser.navigateToInstanceTab('Databases'); - await browser.waitUntil(async () => { - const placeholders = await browser.$$(Selectors.DatabaseStatLoader); - return placeholders.length === 0; - }); // Make sure the db card we're going to drop is in there. await browser.scrollToVirtualItem( @@ -156,7 +152,13 @@ describe('Instance databases tab', function () { ); await browser.$(dbSelector).waitForDisplayed(); - // Drop the database using hte driver + // Wait for the page to finish loading as best as we can + await browser.waitUntil(async () => { + const placeholders = await browser.$$(Selectors.DatabaseStatLoader); + return placeholders.length === 0; + }); + + // Drop the database using the driver const mongoClient = new MongoClient(DEFAULT_CONNECTION_STRING); await mongoClient.connect(); try { From 362e995373fa56f8bbd01d012b2082f7a4f8e09e Mon Sep 17 00:00:00 2001 From: Le Roux Bodenstein Date: Wed, 6 Mar 2024 15:51:43 +0000 Subject: [PATCH 8/8] without the only --- packages/compass-e2e-tests/tests/instance-databases-tab.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1ca27fc4319..91cf48f132a 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -137,7 +137,7 @@ describe('Instance databases tab', function () { await browser.waitUntilActiveInstanceTab('Databases'); }); - it.only('can refresh the list of databases using refresh controls', async function () { + it('can refresh the list of databases using refresh controls', async function () { const db = 'test'; // added by beforeEach const dbSelector = Selectors.databaseCard(db);