From 1ec0d9a0bea1a60fa7511f7ccd69483f3b2e74c5 Mon Sep 17 00:00:00 2001 From: Chris-MS-896 <64865559+Chris-MS-896@users.noreply.github.com> Date: Thu, 18 Feb 2021 07:40:58 -0600 Subject: [PATCH] End to end testcase for mongoDb index policy (#426) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 'update for index policy' * input * 'refactor for ci/cd' * 'refactor for ci/cd' * no message * 'refractor' * 'format change' * added changes * "refactor" * ‘test lint’ * "format" * “push setting back” * ‘refractor’ * Update test/utils/shared.ts Co-authored-by: Steve Faulkner Co-authored-by: Srinath Narayanan Co-authored-by: Steve Faulkner --- .env.example | 2 + test/mongo/mongoIndexPolicy.spec.ts | 121 ++++++++++++++++++++++++++++ test/utils/shared.ts | 49 +++++++++++ 3 files changed, 172 insertions(+) create mode 100644 test/mongo/mongoIndexPolicy.spec.ts diff --git a/.env.example b/.env.example index 2e6e7e5b9..62538cbc0 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,8 @@ PORTAL_RUNNER_SUBSCRIPTION= PORTAL_RUNNER_RESOURCE_GROUP= PORTAL_RUNNER_DATABASE_ACCOUNT= PORTAL_RUNNER_DATABASE_ACCOUNT_KEY= +PORTAL_RUNNER_MONGO_DATABASE_ACCOUNT= +PORTAL_RUNNER_MONGO_DATABASE_ACCOUNT_KEY= PORTAL_RUNNER_CONNECTION_STRING= NOTEBOOKS_TEST_RUNNER_TENANT_ID= NOTEBOOKS_TEST_RUNNER_CLIENT_ID= diff --git a/test/mongo/mongoIndexPolicy.spec.ts b/test/mongo/mongoIndexPolicy.spec.ts new file mode 100644 index 000000000..9fdef93a9 --- /dev/null +++ b/test/mongo/mongoIndexPolicy.spec.ts @@ -0,0 +1,121 @@ +import "expect-puppeteer"; +import { getTestExplorerFrame } from "../testExplorer/TestExplorerUtils"; +import { createDatabase, onClickSaveButton } from "../utils/shared"; +import { generateUniqueName } from "../utils/shared"; +import { ApiKind } from "../../src/Contracts/DataModels"; + +const LOADING_STATE_DELAY = 3000; +const CREATE_DELAY = 5000; +jest.setTimeout(300000); + +describe("MongoDB Index policy tests", () => { + it("Open, Create and Save Index", async () => { + try { + const singleFieldId = generateUniqueName("key"); + const wildCardId = generateUniqueName("key") + "$**"; + const frame = await getTestExplorerFrame(ApiKind.MongoDB); + const dropDown = "Index Type "; + let index = 0; + + //open dataBaseMenu + await frame.waitForSelector('div[class="splashScreen"] > div[class="title"]', { visible: true }); + await frame.waitFor(LOADING_STATE_DELAY); + await frame.waitForSelector('div[class="splashScreen"] > div[class="title"]', { visible: true }); + let databases = await frame.$$(`div[class="databaseHeader main1 nodeItem "] > div[class="treeNodeHeader "]`); + if (databases.length === 0) { + await createDatabase(frame); + databases = await frame.$$(`div[class="databaseHeader main1 nodeItem "] > div[class="treeNodeHeader "]`); + } + + const selectedDbId = await frame.evaluate((element) => { + return element.attributes["data-test"].textContent; + }, databases[0]); + + // click on database + await frame.waitFor(`div[data-test="${selectedDbId}"]`); + await frame.waitFor(LOADING_STATE_DELAY); + await frame.click(`div[data-test="${selectedDbId}"]`); + await frame.waitFor(LOADING_STATE_DELAY); + + // click on scale & setting + const containers = await frame.$$( + `div[class="nodeChildren"] > div[class="collectionHeader main2 nodeItem "]> div[class="treeNodeHeader "]` + ); + const selectedContainer = await frame.evaluate((element) => { + return element.attributes["data-test"].textContent; + }, containers[0]); + await frame.waitFor(`div[data-test="${selectedContainer}"]`), { visible: true }; + await frame.waitFor(LOADING_STATE_DELAY); + await frame.click(`div[data-test="${selectedContainer}"]`); + + await frame.waitFor(`div[data-test="Scale & Settings"]`), { visible: true }; + await frame.waitFor(LOADING_STATE_DELAY); + await frame.click(`div[data-test="Scale & Settings"]`); + + await frame.waitFor(`button[data-content="Indexing Policy"]`), { visible: true }; + await frame.waitFor(LOADING_STATE_DELAY); + await frame.click(`button[data-content="Indexing Policy"]`); + + // Type to single Field + let throughput = await frame.$$(".ms-TextField-field"); + const selectedDropDownSingleField = dropDown + index; + await frame.waitFor(`div[aria-label="${selectedDropDownSingleField}"]`), { visible: true }; + await throughput[index].type(singleFieldId); + await frame.click(`div[aria-label="${selectedDropDownSingleField}"]`); + await frame.waitFor(LOADING_STATE_DELAY); + await frame.click(`button[title="Single Field"]`); + index++; + + // Type to wild card + throughput = await frame.$$(".ms-TextField-field"); + await throughput[index].type(wildCardId); + const selectedDropDownWildCard = dropDown + index; + await frame.waitFor(`div[aria-label="${selectedDropDownWildCard}"]`), { visible: true }; + await frame.click(`div[aria-label="${selectedDropDownWildCard}"]`); + await frame.waitFor(LOADING_STATE_DELAY); + await frame.click(`button[title="Wildcard"]`); + index++; + + // click save Button + await onClickSaveButton(frame); + + // check the array + let singleFieldIndexInserted = false, + wildCardIndexInserted = false; + await frame.waitFor("div[data-automationid='DetailsRowCell'] > span"), { visible: true }; + + const elements = await frame.$$("div[data-automationid='DetailsRowCell'] > span"); + for (let i = 0; i < elements.length; i++) { + const element = elements[i]; + const text = await frame.evaluate((element) => element.textContent, element); + if (text.includes(wildCardId)) { + wildCardIndexInserted = true; + } else if (text.includes(singleFieldId)) { + singleFieldIndexInserted = true; + } + } + await frame.waitFor(LOADING_STATE_DELAY); + expect(wildCardIndexInserted).toBe(true); + expect(singleFieldIndexInserted).toBe(true); + + //delete all index policy + await frame.waitFor("button[aria-label='Delete index Button']"), { visible: true }; + const deleteButton = await frame.$$("button[aria-label='Delete index Button']"); + for (let i = 0; i < deleteButton.length; i++) { + await frame.click(`button[aria-label="Delete index Button"]`); + } + await onClickSaveButton(frame); + + //check for cleaning + await frame.waitFor(CREATE_DELAY); + await frame.waitFor("div[data-automationid='DetailsRowCell'] > span"), { visible: true }; + const isDeletionComplete = await frame.$$("div[data-automationid='DetailsRowCell'] > span"); + expect(isDeletionComplete).toHaveLength(2); + } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const testName = (expect as any).getState().currentTestName; + await page.screenshot({ path: `Test Failed ${testName}.jpg` }); + throw error; + } + }); +}); diff --git a/test/utils/shared.ts b/test/utils/shared.ts index 2f7a92705..ae6ebf8ce 100644 --- a/test/utils/shared.ts +++ b/test/utils/shared.ts @@ -1,6 +1,9 @@ import crypto from "crypto"; import { Frame } from "puppeteer"; +const LOADING_STATE_DELAY = 3000; +const CREATE_DELAY = 10000; + export async function login(connectionString: string): Promise { const prodUrl = process.env.DATA_EXPLORER_ENDPOINT; await page.goto(prodUrl); @@ -22,3 +25,49 @@ export async function login(connectionString: string): Promise { export function generateUniqueName(baseName = "", length = 4): string { return `${baseName}${crypto.randomBytes(length).toString("hex")}`; } + +export async function createDatabase(frame: Frame) { + const dbId = generateUniqueName("db"); + const collectionId = generateUniqueName("col"); + const shardKey = generateUniqueName(); + // create new collection + await frame.waitFor('button[data-test="New Collection"]', { visible: true }); + await frame.click('button[data-test="New Collection"]'); + + // check new database + await frame.waitFor('input[data-test="addCollection-createNewDatabase"]'); + await frame.click('input[data-test="addCollection-createNewDatabase"]'); + + // check shared throughput + await frame.waitFor('input[data-test="addCollectionPane-databaseSharedThroughput"]'); + await frame.click('input[data-test="addCollectionPane-databaseSharedThroughput"]'); + + // type database id + await frame.waitFor('input[data-test="addCollection-newDatabaseId"]'); + const dbInput = await frame.$('input[data-test="addCollection-newDatabaseId"]'); + await dbInput.press("Backspace"); + await dbInput.type(dbId); + + // type collection id + await frame.waitFor('input[data-test="addCollection-collectionId"]'); + const input = await frame.$('input[data-test="addCollection-collectionId"]'); + await input.press("Backspace"); + await input.type(collectionId); + + // type partition key value + await frame.waitFor('input[data-test="addCollection-partitionKeyValue"]'); + const keyInput = await frame.$('input[data-test="addCollection-partitionKeyValue"]'); + await keyInput.press("Backspace"); + await keyInput.type(shardKey); + + // click submit + await frame.waitFor("#submitBtnAddCollection"); + await frame.click("#submitBtnAddCollection"); +} + +export async function onClickSaveButton(frame: Frame) { + await frame.waitFor(`button[data-test="Save"]`), { visible: true }; + await frame.waitFor(LOADING_STATE_DELAY); + await frame.click(`button[data-test="Save"]`); + await frame.waitFor(CREATE_DELAY); +}