From e66177c990d308ad15ed4bec57cfa21957354631 Mon Sep 17 00:00:00 2001 From: "Anusha Kopuri (GLOBALLOGIC INDIA PRIVATE LIMI)" Date: Mon, 7 Oct 2024 17:52:26 +0530 Subject: [PATCH] Refactored the code --- src/web/client/common/constants.ts | 145 +++++ src/web/client/common/interfaces.ts | 16 + .../copilotPromptsValidation.test.ts | 588 ++++++------------ ...pilotPromptsValidationAdvancedForm.test.ts | 268 ++------ .../copilotPromptsValidationHTMLnCSS.test.ts | 569 ++++++----------- .../copilotPromptsValidationList.test.ts | 290 +++------ .../client/utilities/copilotAutomationUtil.ts | 195 ++++-- 7 files changed, 824 insertions(+), 1247 deletions(-) diff --git a/src/web/client/common/constants.ts b/src/web/client/common/constants.ts index bc2d613b6..6926ee341 100644 --- a/src/web/client/common/constants.ts +++ b/src/web/client/common/constants.ts @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ +import { EXTENSION_NAME } from "../../../common/constants"; +import { getExtensionVersion } from "../../../common/utilities/Utils"; + // Default and constants export const PORTAL_LANGUAGE_DEFAULT = "1033"; export const PORTALS_FOLDER_NAME_DEFAULT = "site"; @@ -135,3 +138,145 @@ export const WEB_EXTENSION_SEND_EMAIL_NOT_AVAILABLE = "Send email is not availab export const WEB_EXTENSION_QUICK_PICK_TITLE = "People on this file" export const WEB_EXTENSION_QUICK_PICK_PLACEHOLDER = "Search for people"; export const WEB_EXTENSION_COLLABORATION_OPTIONS_CONTACT = "Contact"; + +export enum FormConstants { + BasicForm = '[aria-label="Basic Form"]', + EmailField = '[aria-label="Email"]', + SubjectField = '[id="title"]', + MessageField = '[aria-label="Message"]', + SubmitButton = '[id="InsertButton"]', + NameIsRequired = "//li[text()='Name is a required field.']", + NameField = 'input[id="adx_createdbycontact"]', + MinimumRating = 'input[id="minrating"]', + MaximumRating = 'input[id="maxrating"]', + SubmissionSuccessful = "//span[text()='Submission completed successfully.']", + ValidEmail = "//li[text()='Please enter a valid email address.']", + SpecialCharacters = "//li[text()='{0} cannot contain special characters.']", + Lessthan5Characters = "//li[text()='Name must be less than 5 characters.']", + ValidationSummary = '[class*="validation-summary"]', + RatingBeAtleast10 = "//li[text()='Minimum rating must be at least 10.']", + RatingBeAtmost95 = "//li[text()='Maximum Rating must not be greater than 95.']", + RatingBeAtleast5 = "//li[text()='Minimum Rating must be at least 5.']", + RatingAtmost95 = "//li[text()='Maximum Rating must be at most 95.']", +} + +export enum ListConstants { + DataRecord = 'tr[data-name="rf"]', + AmountColumn = '[data-attribute="cr1ae_amount"]', +} + +export enum AdvanceFormConstants { + PhoneField = '#telephone1', + NameField = '#name', + NextButton = '#NextButton', + EmailField = '#emailaddress1', + ValidationSummary = '#ValidationSummaryEntityFormView li', + PreviousButton = '#PreviousButton', + AccountNumber = '#accountnumber', + MessageLabel = '#MessageLabel' +} + +export enum PageConstants { + TestButton = "//button[text()='Test']", + MicrosoftURL = 'https://www.microsoft.com/en-in/', + MicrosoftLogo = 'img[alt="Microsoft Logo"]', + Button = '[type="button"][class*="button"]', + RedColor = 'rgb(255, 0, 0)', + Button1 = '[class="button1"]', + YellowColor = 'rgb(255, 255, 0)', + Section = '.sectionBlockLayout:first-of-type', + GreenColor = 'rgb(0, 128, 0)' +} + +export enum TextConstants{ + MicrosoftURL = 'https://www.microsoft.com/en-in/', + Italic = 'italic' +} + +export enum FormQueries { + Query1 = "Write JavaScript code for name field validation in form.", + Query2 = "Write JavaScript code to hide email field in form.", + Query3 = "Write JavaScript code to disable email field in form.", + Query4 = "Write JavaScript code for form field validation to check email field value is in the valid format.", + Query5 = "Write JavaScript code to add field validation to check for the length of the name field to be less than 5", + Query6 = "Write Javascript code to add field validation to check for the value of the minimum rating field to not to be less than 10.", + Query7 = "Write Javascript code to add field validation to check for the value of the maximum rating field to not to be greater than 95.", + Query8 = "Write Javascript code to add field validation to check for the value of the minimum rating field to not to be less than 5 and maximum rating not to be greater than 95." +} +export enum AdvancedFormQueries { + Query1 = "Write JavaScript code for Phone field validation to check phone field value is in the valid format.", + Query2 = "Write javascript code to rename Next button to Forward", + Query3 = "Write javascript code to make Phone field a required field", + Query4 = "Write javascript code for Account Number field to accept only numbers", + Query5 = "Write javascript code to make email field readonly in the form", +} + +export enum ListQueries { + Query1 = "Write JavaScript code to highlight the row where title column value is rf in table list.", + Query2 = "Write javascript code to Mark rows with amount > 500 with yellow and amount datatype is dollars", + Query3 = "write javascript code to arrange amount column values in descending order", + Query4 = "write javascript code to arrange amount column values in ascending order", +} + +export enum HtmlQueries { + Query1 = "Write code to add 'Account' entity form to my webpage 'html' with some section code.", + Query2 = "Write code to add a button with name Test which should redirect to microsoft.com url.", + Query3 = "Write html code to add an image for microsoft and choose image from online", +} + +export enum CssQueries { + Query1 = "Write css code to change the first section color of home page to yellow", + Query2 = "Write css code to change first existing button background color to red", + Query3 = "Write css code to change button text to italic for all buttons", + Query4 = "Write css code to update first existing button background color to green important on hover", +} + +export enum Paths{ + HtmlWebpageCopy = "C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-uo67k\\web-pages\\html\\content-pages\\Html.en-US.webpage.copy.html", + HomePageCss = 'C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-uo67k\\web-pages\\home\\content-pages\\Home.en-US.webpage.custom_css.css', + ListJsFile = 'C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-uo67k\\lists\\Active-Feedback.list.custom_javascript.js', + FormJsFile = 'C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-uo67k\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', + AdvFormStep1JsFile = 'C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-uo67k\\advanced-forms\\multistep-form-1\\advanced-form-steps\\step1\\Step1.advancedformstep.custom_javascript.js', + AdvFormStep2JsFile = 'C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-uo67k\\advanced-forms\\multistep-form-1\\advanced-form-steps\\step2\\Step2.advancedformstep.custom_javascript.js' +} + +// Copilot constants +export const AIB_ENDPOINT = 'https://aibuildertextapiservice.us-il108.gateway.prod.island.powerapps.com/v1.0/63efacda-3db4-ee11-a564-000d3a106f1e/appintelligence/chat'; + + +// JSON request to be sent to the API. +export const ApiRequestJson = { + "question": "{0}", + "top": 1, + "context": + { + "scenario": "PowerPagesProDev", + "subScenario": "PowerPagesProDevGeneric", + "version": "V1", + "information": + { + "activeFileContent": "{6}", + "dataverseEntity": "{2}", + "entityField": "{3}", + "fieldType": "{4}", + "targetEntity": "{5}", + "targetColumns": "{1}", // Placeholder value for targetColumns + "clientType": EXTENSION_NAME + '-' + 'Desktop', + "clientVersion": getExtensionVersion() + } + } +}; + +export const ExpectedResponses = { + COPILOT_IT_UNSUPPORTED_EXPECTED_RESPONSE: { + "displayText":"Try a different prompt that’s related to writing code for Power Pages sites. You can get help with HTML, CSS, and JS languages.", + "Code":"violation", + "language":"text", + "useCase":"unsupported" + } +}; + +export const SuggestedPromptsConstants : Record = { + // Name: "Write javascript code to validate name field to not accept special characters", + Subject: "Write javascript code to validate subject field to not accept special characters", +} \ No newline at end of file diff --git a/src/web/client/common/interfaces.ts b/src/web/client/common/interfaces.ts index 850d752e2..a7a78edbe 100644 --- a/src/web/client/common/interfaces.ts +++ b/src/web/client/common/interfaces.ts @@ -4,6 +4,7 @@ */ import * as vscode from 'vscode'; +import fs from 'fs'; export interface IEntityRequestUrl { requestUrl: string; @@ -38,3 +39,18 @@ export interface ISearchQueryResults { matches: ISearchQueryMatch[]; limitHit: boolean; } + +export interface IApiRequestParams { + aibEndPoint: string; + apiToken: string; + data: unknown; +} + +export interface ITestLogParams { + testName: string, + testStartTime: Date, + testEndTime: Date, + actualResponse: string, + status: string, + logStream: fs.WriteStream +} diff --git a/src/web/client/test/integration/copilotPromptsValidation.test.ts b/src/web/client/test/integration/copilotPromptsValidation.test.ts index 7a0672ce0..3a697cb99 100644 --- a/src/web/client/test/integration/copilotPromptsValidation.test.ts +++ b/src/web/client/test/integration/copilotPromptsValidation.test.ts @@ -3,305 +3,154 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { AIB_ENDPOINT, CreateAndExecuteAPIRequest, getIntelligenceAPIAccessToken, log, ITestLogParams, getFormattedDateTime, writeHeading, writeTableHeaders, closeHtmlFile, ReturnFormattedAPIResponse, SuggestedPromptsConstants, formatString, verifyAPIResponse, uploadPortal, LaunchRunTime } from '../../utilities/copilotAutomationUtil'; +import { CreateAndExecuteAPIRequest, closeHtmlFile, ReturnFormattedAPIResponse, verifyAPIResponse, uploadPortal, LaunchRunTime, reportingForTests, reportAfterTestCompletes, getAccessToken, writeHeadingandTableHeaders, formatString } from '../../utilities/copilotAutomationUtil'; +import { AIB_ENDPOINT, FormConstants, FormQueries, Paths, SuggestedPromptsConstants } from '../../common/constants'; const aibEndPoint = AIB_ENDPOINT; -let accessToken : string; +let accessToken: string; import fs from 'fs'; -import path from 'path'; import { expect } from 'playwright/test'; -const testReportPath = path.resolve(__dirname, `../test-reports`); // testReportPath => ..\powerplatform-vscode\out\web\client\test\test-reports - -// Ensure the log directory exists -if (!fs.existsSync(testReportPath)) { - fs.mkdirSync(testReportPath); -} - -const formattedDateTime = getFormattedDateTime(); - -// Create a write stream to the HTML file -const logFilePath = path.join(testReportPath, `test-report-${formattedDateTime}.html`); -const logStream = fs.createWriteStream(logFilePath, { flags: 'w' }); - -// Open the HTML file with initial structure -logStream.write(` - - - - Copilot Integration Test Report - - - -

Copilot Integration Test Report

-`); + +const logStream = reportingForTests(); // Overriding the default 10 sec. timeout and setting it to 60 sec. before(async function () { if (aibEndPoint === undefined) throw new Error("Endpoint is not defined. Test will fail intentionally."); this.timeout(120000); - const apiToken = await getIntelligenceAPIAccessToken(); - accessToken = apiToken.accessToken; + accessToken = await getAccessToken(); // Write heading and table headers to the HTML file - writeHeading(logStream, `${AIB_ENDPOINT}`); - writeTableHeaders(logStream); + await writeHeadingandTableHeaders(logStream); }); // Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write JavaScript code for name field validation in form."; - it(testName, async () => { - // const testStartTime = new Date(); +describe('Copilot SUGGESTED prompts integration tests', async function () { + it(FormQueries.Query1, async () => { + const testStartTime = new Date(); + const testName = FormQueries.Query1; - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - // ["adx_createdbycontact"], - "Name,adx_createdbycontact,,Email,adx_contactemail,,Subject,title,,Message,comments,,Maximum Rating,maxrating,,Minimum Rating,minrating,,Status Reason,statuscode","adx_entityform","","","feedback" - ]; - - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "Name,adx_createdbycontact,,Email,adx_contactemail,,Subject,title,,Message,comments,,Maximum Rating,maxrating,,Minimum Rating,minrating,,Status Reason,statuscode","adx_entityform","","","feedback" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const page = await LaunchRunTime('contact-us') + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('contact-us') - await page.locator('[aria-label="Email"]').fill('abcd@abc.com'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); + await page.locator(FormConstants.EmailField).fill('abcd@abc.com'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); - await page.locator('[id="InsertButton"]').click(); - await expect(page.locator("//li[text()='Name is a required field.']")).toBeVisible(); - await page.close(); + await page.locator(FormConstants.SubmitButton).click(); + await expect(page.locator(FormConstants.NameIsRequired)).toBeVisible(); + await page.close(); - // Record end time after test execution - // const testEndTime = new Date(); - - /* const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); */ - - }).timeout(120000); -}); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write JavaScript code to hide email field in form."; - it(testName, async () => { - const testStartTime = new Date(); + it(FormQueries.Query2, async () => { + const testStartTime = new Date(); + const testName = FormQueries.Query2; - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - ["adx_contactemail"], - ]; - - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); - - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + ["adx_contactemail"], + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const page = await LaunchRunTime('contact-us') - await page.locator('input[id="adx_createdbycontact"]').fill('Text name'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); - await expect(page.locator('[aria-label="Email"]')).toBeHidden(); - await page.close(); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('contact-us') + await page.locator(FormConstants.NameField).fill('Text name'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); + await expect(page.locator(FormConstants.EmailField)).toBeHidden(); + await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); -}); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write JavaScript code to disable email field in form."; - it(testName, async () => { - const testStartTime = new Date(); + it(FormQueries.Query3, async () => { + const testStartTime = new Date(); + const testName = FormQueries.Query3; - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - // ["adx_contactemail"], - "Name,adx_createdbycontact,,Email,adx_contactemail,,Subject,title,,Message,comments,,Maximum Rating,maxrating,,Minimum Rating,minrating,,Status Reason,statuscode","adx_entityform","","","feedback" - ]; - - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "Name,adx_createdbycontact,,Email,adx_contactemail,,Subject,title,,Message,comments,,Maximum Rating,maxrating,,Minimum Rating,minrating,,Status Reason,statuscode","adx_entityform","","","feedback" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const page = await LaunchRunTime('contact-us') + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('contact-us') - await page.locator('input[id="adx_createdbycontact"]').fill('Text name'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); + await page.locator(FormConstants.NameField).fill('Text name'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); - await expect(page.locator('[aria-label="Email"]')).toBeDisabled(); - await page.close(); + await expect(page.locator(FormConstants.EmailField)).toBeDisabled(); + await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); -}); + // Record end time after test execution + await reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write JavaScript code for form field validation to check email field value is in the valid format."; - it(testName, async () => { - const testStartTime = new Date(); + it(FormQueries.Query4, async () => { + const testStartTime = new Date(); + const testName = FormQueries.Query4 - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - //["adx_contactemail"],"adx_entityform","","","feedback" - "Name,adx_createdbycontact,,Email,adx_contactemail,,Subject,title,,Message,comments,,Maximum Rating,maxrating,,Minimum Rating,minrating,,Status Reason,statuscode","adx_entityform","","","feedback" - ]; - - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "Name,adx_createdbycontact,,Email,adx_contactemail,,Subject,title,,Message,comments,,Maximum Rating,maxrating,,Minimum Rating,minrating,,Status Reason,statuscode","adx_entityform","","","feedback" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response + // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('contact-us') - await page.locator('input[id="adx_createdbycontact"]').fill('Text name'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); - await page.locator('[aria-label="Email"]').fill('abcd'); + await page.locator(FormConstants.NameField).fill('Text name'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); + await page.locator(FormConstants.EmailField).fill('abcd'); - await page.locator('[id="InsertButton"]').click(); - await expect(page.locator("//li[text()='Please enter a valid email address.']")).toBeVisible(); + await page.locator(FormConstants.SubmitButton).click(); + await expect(page.locator(FormConstants.ValidEmail)).toBeVisible(); await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); -}); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); -describe('Copilot SUGGESTED prompts integration tests', async function () { - Object.keys(SuggestedPromptsConstants).forEach(function (promptKey) { - const testName = `${SuggestedPromptsConstants[promptKey]}`; - it(testName, async () => { + + Object.keys(SuggestedPromptsConstants).forEach(function (promptKey) { + it(`${SuggestedPromptsConstants[promptKey]}`, async () => { const testStartTime = new Date(); + const testName = `${SuggestedPromptsConstants[promptKey]}`; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -309,48 +158,37 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { "Name,adx_createdbycontact,,Email,adx_contactemail,,Subject,title,,Message,comments,,Maximum Rating,maxrating,,Minimum Rating,minrating,,Status Reason,statuscode","adx_entityform","","","feedback" ]; const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('contact-us') - await page.locator('input[id="adx_createdbycontact"]').fill('Test name!@#$%^&*()'); - await page.locator('[id="title"]').fill('Test title@%&%&'); - await page.locator('[aria-label="Message"]').fill('Message'); - await page.locator('[aria-label="Email"]').fill('abcd@abc.com'); - await page.locator('[id="InsertButton"]').click(); + await page.locator(FormConstants.NameField).fill('Test name!@#$%^&*()'); + await page.locator(FormConstants.SubjectField).fill('Test title@%&%&'); + await page.locator(FormConstants.MessageField).fill('Message'); + await page.locator(FormConstants.EmailField).fill('abcd@abc.com'); + await page.locator(FormConstants.SubmitButton).click(); - await expect(page.locator(formatString("//li[text()='{0} cannot contain special characters.']",promptKey))).toBeVisible(); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('input[id="adx_createdbycontact"]').fill('Test name'); - await page.locator('[id="InsertButton"]').click(); - await expect(page.locator(formatString("//li[text()='{0} cannot contain special characters.']",promptKey))).not.toBeVisible(); - await expect(page.locator("//span[text()='Submission completed successfully.']")).toBeVisible(); + await expect(page.locator(formatString(FormConstants.SpecialCharacters,promptKey))).toBeVisible(); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.NameField).fill('Test name'); + await page.locator(FormConstants.SubmitButton).click(); + await expect(page.locator(formatString(FormConstants.SpecialCharacters,promptKey))).not.toBeVisible(); + await expect(page.locator(FormConstants.SubmissionSuccessful)).toBeVisible(); await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); }); -}); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write JavaScript code to add field validation to check for the length of the name field to be less than 5"; - it(testName, async () => { + it(FormQueries.Query5, async () => { const testStartTime = new Date(); + const testName = FormQueries.Query5; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -358,40 +196,31 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { "Name,adx_createdbycontact","adx_entityform","","","feedback" ]; const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('contact-us'); - await page.locator('input[id="adx_createdbycontact"]').fill('Text name'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); - await page.locator('[aria-label="Email"]').fill('abcd'); - await page.locator('[id="InsertButton"]').click(); - await expect(page.locator("//li[text()='Name must be less than 5 characters.']")).toBeVisible(); + await page.locator(FormConstants.NameField).fill('Text name'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); + await page.locator(FormConstants.EmailField).fill('abcd'); + await page.locator(FormConstants.SubmitButton).click(); + await expect(page.locator(FormConstants.Lessthan5Characters)).toBeVisible(); await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); -}); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write Javascript code to add field validation to check for the value of the minimum rating field to not to be less than 10."; - it(testName, async () => { + + + it(FormQueries.Query6, async () => { const testStartTime = new Date(); + const testName = FormQueries.Query6; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -399,46 +228,36 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { "Minimum Rating,minrating","adx_entityform","","","feedback" ]; const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('contact-us') - await page.locator('input[id="adx_createdbycontact"]').fill('Text name'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); - await page.locator('[aria-label="Email"]').fill('abcd@abc.com'); - await page.locator('input[id="minrating"]').fill('9'); - await page.locator('[id="InsertButton"]').click(); - - expect((await page.locator('[class*="validation-summary"]').innerText()).toLowerCase()).toContain('minimum rating must be at least 10.'); - await page.locator('input[id="minrating"]').fill('10'); - await page.locator('[id="InsertButton"]').click(); - await expect(page.locator("//li[text()='Minimum rating must be at least 10.']")).not.toBeVisible(); - await expect(page.locator("//span[text()='Submission completed successfully.']")).toBeVisible(); + await page.locator(FormConstants.NameField).fill('Text name'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); + await page.locator(FormConstants.EmailField).fill('abcd@abc.com'); + await page.locator(FormConstants.MinimumRating).fill('9'); + await page.locator(FormConstants.SubmitButton).click(); + + expect((await page.locator(FormConstants.ValidationSummary).innerText()).toLowerCase()).toContain('minimum rating must be at least 10.'); + await page.locator(FormConstants.MinimumRating).fill('10'); + await page.locator(FormConstants.SubmitButton).click(); + await expect(page.locator(FormConstants.RatingBeAtleast10)).not.toBeVisible(); + await expect(page.locator(FormConstants.SubmissionSuccessful)).toBeVisible(); await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); -}); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write Javascript code to add field validation to check for the value of the maximum rating field to not to be greater than 95."; - it(testName, async () => { + + it(FormQueries.Query7, async () => { const testStartTime = new Date(); + const testName = FormQueries.Query7; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -446,44 +265,37 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { "Maximum Rating,maxrating","adx_entityform","","","feedback" ]; const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); + // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + await verifyAPIResponse(response); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const page = await LaunchRunTime('contact-us') + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('contact-us') + + await page.locator(FormConstants.NameField).fill('Text name'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); + await page.locator(FormConstants.EmailField).fill('abcd@abc.com'); + + await page.locator(FormConstants.MaximumRating).fill('96'); + await page.locator(FormConstants.SubmitButton).click(); + await expect(page.locator(FormConstants.RatingBeAtmost95)).toBeVisible(); + await page.locator(FormConstants.MaximumRating).fill('95'); + await page.locator(FormConstants.SubmitButton).click(); - await page.locator('input[id="adx_createdbycontact"]').fill('Text name'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); - await page.locator('[aria-label="Email"]').fill('abcd@abc.com'); - await page.locator('input[id="maxrating"]').fill('96'); - await page.locator('[id="InsertButton"]').click(); - await expect(page.locator("//li[text()='Maximum Rating must not be greater than 95.']")).toBeVisible(); - await page.locator('input[id="maxrating"]').fill('95'); - await page.locator('[id="InsertButton"]').click(); - await expect(page.locator("//li[text()='Maximum Rating must not be greater than 95.']")).not.toBeVisible(); - await expect(page.locator("//span[text()='Submission completed successfully.']")).toBeVisible(); + await expect(page.locator(FormConstants.RatingBeAtmost95)).not.toBeVisible(); + await expect(page.locator(FormConstants.SubmissionSuccessful)).toBeVisible(); await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); -}); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write Javascript code to add field validation to check for the value of the minimum rating field to not to be less than 5 and maximum rating not to be greater than 95."; - it(testName, async () => { + + it(FormQueries.Query8, async () => { const testStartTime = new Date(); + const testName = FormQueries.Query8; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -491,45 +303,36 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { "Maximum Rating,maxrating,Minimum Rating,minrating","adx_entityform","","","feedback" ]; const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\basic-forms\\simple-contact-us-form\\simple-contact-us-form.basicform.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.FormJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('contact-us') - await page.locator('input[id="adx_createdbycontact"]').fill('Text name'); - await page.locator('[id="title"]').fill('Test title'); - await page.locator('[aria-label="Message"]').fill('Message'); - await page.locator('[aria-label="Email"]').fill('abcd@abc.com'); - await page.locator('input[id="minrating"]').fill('4'); - await page.locator('input[id="maxrating"]').fill('96'); - await page.locator('[id="InsertButton"]').click(); - - await expect(page.locator("//li[text()='Minimum Rating must be at least 5.']")).toBeVisible(); - await expect(page.locator("//li[text()='Maximum Rating must be at most 95.']")).toBeVisible(); - await page.locator('input[id="minrating"]').fill('10'); - await page.locator('input[id="maxrating"]').fill('90'); - await page.locator('[id="InsertButton"]').click(); - - await expect(page.locator("//li[text()='Minimum Rating must be at least 5.']")).not.toBeVisible(); - await expect(page.locator("//li[text()='Maximum Rating must be at most 95.']")).not.toBeVisible(); - await expect(page.locator("//span[text()='Submission completed successfully.']")).toBeVisible(); + await page.locator(FormConstants.NameField).fill('Text name'); + await page.locator(FormConstants.SubjectField).fill('Test title'); + await page.locator(FormConstants.MessageField).fill('Message'); + await page.locator(FormConstants.EmailField).fill('abcd@abc.com'); + await page.locator(FormConstants.MinimumRating).fill('4'); + await page.locator(FormConstants.MaximumRating).fill('96'); + await page.locator(FormConstants.SubmitButton).click(); + + await expect(page.locator(FormConstants.RatingBeAtleast5)).toBeVisible(); + await expect(page.locator(FormConstants.RatingAtmost95)).toBeVisible(); + await page.locator(FormConstants.MinimumRating).fill('10'); + await page.locator(FormConstants.MaximumRating).fill('90'); + await page.locator(FormConstants.SubmitButton).click(); + + await expect(page.locator(FormConstants.RatingBeAtleast5)).not.toBeVisible(); + await expect(page.locator(FormConstants.RatingAtmost95)).not.toBeVisible(); + await expect(page.locator(FormConstants.SubmissionSuccessful)).toBeVisible(); await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); }); @@ -539,5 +342,4 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // and use the `after` hook to close the logStream after all tests have completed. after(async function () { closeHtmlFile(logStream); -}); - +}); \ No newline at end of file diff --git a/src/web/client/test/integration/copilotPromptsValidationAdvancedForm.test.ts b/src/web/client/test/integration/copilotPromptsValidationAdvancedForm.test.ts index e2d84ee6f..f156b8eb6 100644 --- a/src/web/client/test/integration/copilotPromptsValidationAdvancedForm.test.ts +++ b/src/web/client/test/integration/copilotPromptsValidationAdvancedForm.test.ts @@ -3,110 +3,29 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { AIB_ENDPOINT, CreateAndExecuteAPIRequest, getIntelligenceAPIAccessToken, log, ITestLogParams, getFormattedDateTime, writeHeading, writeTableHeaders, closeHtmlFile, ReturnFormattedAPIResponse, LaunchRunTime, uploadPortal, verifyAPIResponse } from '../../utilities/copilotAutomationUtil'; +import { CreateAndExecuteAPIRequest, closeHtmlFile, ReturnFormattedAPIResponse, verifyAPIResponse, uploadPortal, LaunchRunTime, reportingForTests, reportAfterTestCompletes, getAccessToken, writeHeadingandTableHeaders } from '../../utilities/copilotAutomationUtil'; +import { AIB_ENDPOINT, AdvanceFormConstants, AdvancedFormQueries, Paths } from '../../common/constants'; const aibEndPoint = AIB_ENDPOINT; -let accessToken : string; +let accessToken: string; import fs from 'fs'; -import path from 'path'; import { expect } from 'playwright/test'; -const testReportPath = path.resolve(__dirname, `../test-reports`); // testReportPath => ..\powerplatform-vscode\out\web\client\test\test-reports -// Ensure the log directory exists -if (!fs.existsSync(testReportPath)) { - fs.mkdirSync(testReportPath); -} -const formattedDateTime = getFormattedDateTime(); -// Create a write stream to the HTML file -const logFilePath = path.join(testReportPath, `test-report-${formattedDateTime}.html`); -const logStream = fs.createWriteStream(logFilePath, { flags: 'w' }); -// Open the HTML file with initial structure -logStream.write(` - - - - Copilot Integration Test Report - - - -

Copilot Integration Test Report

-`); -// Overriding the default 10 sec. timeout and setting it to 60 sec. + +const logStream = reportingForTests(); before(async function () { if (aibEndPoint === undefined) throw new Error("Endpoint is not defined. Test will fail intentionally."); this.timeout(120000); - const apiToken = await getIntelligenceAPIAccessToken(); - accessToken = apiToken.accessToken; + accessToken = await getAccessToken(); + // Write heading and table headers to the HTML file - writeHeading(logStream, `${AIB_ENDPOINT}`); - writeTableHeaders(logStream); + await writeHeadingandTableHeaders(logStream); }); // Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write JavaScript code for Phone field validation to check phone field value is in the valid format."; - it.only(testName, async () => { +describe('Copilot SUGGESTED prompts integration tests', async function () { + it(AdvancedFormQueries.Query1, async () => { const testStartTime = new Date(); + const testName = AdvancedFormQueries.Query1; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -117,43 +36,31 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\advanced-forms\\multistep-form-1\\advanced-form-steps\\step1\\Step1.advancedformstep.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.AdvFormStep1JsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('Multistepform'); - await page.locator('#telephone1').fill('abc123'); - await page.locator('#name').fill('Test name'); - await page.locator('#NextButton').click(); + await page.locator(AdvanceFormConstants.PhoneField).fill('abc123'); + await page.locator(AdvanceFormConstants.NameField).fill('Test name'); + await page.locator(AdvanceFormConstants.NextButton).click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).toHaveText('Phone number is not in a valid format.') - await page.locator('#telephone1').fill('+911234567890'); - await page.locator('#NextButton').click(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).toHaveText('Phone number is not in a valid format.') + await page.locator(AdvanceFormConstants.PhoneField).fill('+911234567890'); + await page.locator(AdvanceFormConstants.NextButton).click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).not.toBeVisible(); - await page.locator('#PreviousButton').click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).not.toBeVisible(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).not.toBeVisible(); + await page.locator(AdvanceFormConstants.PreviousButton).click(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).not.toBeVisible(); await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); -}); -// Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write javascript code to rename Next button to Forward"; - it.only(testName, async () => { + it( AdvancedFormQueries.Query2, async () => { const testStartTime = new Date(); + const testName = AdvancedFormQueries.Query2; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -164,35 +71,23 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\advanced-forms\\multistep-form-1\\advanced-form-steps\\step1\\Step1.advancedformstep.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.AdvFormStep1JsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('Multistepform'); - expect(await page.getAttribute('#NextButton','value')).toBe('Forward'); - expect(await page.getAttribute('#NextButton','value')).not.toBe('Next'); + expect(await page.getAttribute(AdvanceFormConstants.NextButton,'value')).toBe('Forward'); + expect(await page.getAttribute(AdvanceFormConstants.NextButton,'value')).not.toBe('Next'); await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); -}); -// Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write javascript code to make Phone field a required field"; - it.only(testName, async () => { + it(AdvancedFormQueries.Query3, async () => { const testStartTime = new Date(); + const testName = AdvancedFormQueries.Query3; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -203,44 +98,32 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\advanced-forms\\multistep-form-1\\advanced-form-steps\\step1\\Step1.advancedformstep.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.AdvFormStep1JsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('Multistepform'); - await page.locator('#name').fill('Test name'); - await page.locator('#NextButton').click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).toHaveText('Phone is a required field.') + await page.locator(AdvanceFormConstants.NameField).fill('Test name'); + await page.locator(AdvanceFormConstants.NextButton).click(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).toHaveText('Phone is a required field.') - await page.locator('#name').fill('Test name'); - await page.locator('#telephone1').fill('911234567890'); - await page.locator('#NextButton').click(); + await page.locator(AdvanceFormConstants.NameField).fill('Test name'); + await page.locator(AdvanceFormConstants.PhoneField).fill('911234567890'); + await page.locator(AdvanceFormConstants.NextButton).click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).not.toBeVisible(); - await page.locator('#PreviousButton').click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).not.toBeVisible(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).not.toBeVisible(); + await page.locator(AdvanceFormConstants.PreviousButton).click(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).not.toBeVisible(); await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(120000); -}); - -// Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write javascript code for Account Number field to accept only numbers"; - it.only(testName, async () => { + + it(AdvancedFormQueries.Query4, async () => { const testStartTime = new Date(); + const testName = AdvancedFormQueries.Query4; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -251,47 +134,35 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\advanced-forms\\multistep-form-1\\advanced-form-steps\\step2\\Step2.advancedformstep.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.AdvFormStep2JsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('Multistepform'); - await page.locator('#name').fill('Test name'); - await page.locator('#NextButton').click(); + await page.locator(AdvanceFormConstants.NameField).fill('Test name'); + await page.locator(AdvanceFormConstants.NextButton).click(); - await page.locator('#accountnumber').fill('123Abc'); - await page.locator('#NextButton').click(); + await page.locator(AdvanceFormConstants.AccountNumber).fill('123Abc'); + await page.locator(AdvanceFormConstants.NextButton).click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).toBeVisible(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).toContainText('Account Number'); - await expect(page.locator('#ValidationSummaryEntityFormView li')).toHaveText('Account Number must be a numeric value.') - await page.locator('#accountnumber').fill('1234567890'); - await page.locator('#NextButton').click(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).toBeVisible(); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).toContainText('Account Number'); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).toHaveText('Account Number must be a numeric value.') + await page.locator(AdvanceFormConstants.AccountNumber).fill('1234567890'); + await page.locator(AdvanceFormConstants.NextButton).click(); - await expect(page.locator('#ValidationSummaryEntityFormView li')).not.toBeVisible(); - await expect(page.locator('#MessageLabel')).toHaveText('Submission completed successfully.'); + await expect(page.locator(AdvanceFormConstants.ValidationSummary)).not.toBeVisible(); + await expect(page.locator(AdvanceFormConstants.MessageLabel)).toHaveText('Submission completed successfully.'); await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(240000); -}); -// Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write javascript code to make email field readonly in the form"; - it.only(testName, async () => { + it(AdvancedFormQueries.Query5, async () => { const testStartTime = new Date(); + const testName = AdvancedFormQueries.Query5; // Actual values to replace placeholders from API request JSON. const actualValues = [ @@ -302,28 +173,19 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\advanced-forms\\multistep-form-1\\advanced-form-steps\\step2\\Step2.advancedformstep.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.AdvFormStep2JsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('Multistepform'); - await page.locator('#name').fill('Test name'); - await page.locator('#NextButton').click(); - await expect(page.locator('#emailaddress1')).toHaveAttribute('readonly'); + await page.locator(AdvanceFormConstants.NameField).fill('Test name'); + await page.locator(AdvanceFormConstants.NextButton).click(); + await expect(page.locator(AdvanceFormConstants.EmailField)).toHaveAttribute('readonly'); await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + reportAfterTestCompletes(testName, testStartTime, response, logStream); }).timeout(240000); }); @@ -332,4 +194,4 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // and use the `after` hook to close the logStream after all tests have completed. after(async function () { closeHtmlFile(logStream); -}); +}); \ No newline at end of file diff --git a/src/web/client/test/integration/copilotPromptsValidationHTMLnCSS.test.ts b/src/web/client/test/integration/copilotPromptsValidationHTMLnCSS.test.ts index 1271600ca..970083195 100644 --- a/src/web/client/test/integration/copilotPromptsValidationHTMLnCSS.test.ts +++ b/src/web/client/test/integration/copilotPromptsValidationHTMLnCSS.test.ts @@ -4,425 +4,234 @@ */ -import { AIB_ENDPOINT, CreateAndExecuteAPIRequest, getIntelligenceAPIAccessToken, log, ITestLogParams, getFormattedDateTime, writeHeading, writeTableHeaders, closeHtmlFile, ReturnFormattedAPIResponse, verifyAPIResponse, uploadPortal, LaunchRunTime } from '../../utilities/copilotAutomationUtil'; +import { CreateAndExecuteAPIRequest, closeHtmlFile, ReturnFormattedAPIResponse, verifyAPIResponse, uploadPortal, LaunchRunTime, reportingForTests, reportAfterTestCompletes, getAccessToken, writeHeadingandTableHeaders } from '../../utilities/copilotAutomationUtil'; +import { AIB_ENDPOINT, CssQueries, FormConstants, HtmlQueries, PageConstants, Paths, TextConstants } from '../../common/constants'; const aibEndPoint = AIB_ENDPOINT; -let accessToken : string; +let accessToken: string; import fs from 'fs'; -import path from 'path'; -import { chromium } from 'playwright'; import { expect } from 'playwright/test'; -const testReportPath = path.resolve(__dirname, `../test-reports`); // testReportPath => ..\powerplatform-vscode\out\web\client\test\test-reports -// Ensure the log directory exists -if (!fs.existsSync(testReportPath)) { - fs.mkdirSync(testReportPath); -} -const formattedDateTime = getFormattedDateTime(); -// Create a write stream to the HTML file -const logFilePath = path.join(testReportPath, `test-report-${formattedDateTime}.html`); -const logStream = fs.createWriteStream(logFilePath, { flags: 'w' }); -// Open the HTML file with initial structure -logStream.write(` - - - - Copilot Integration Test Report - - - -

Copilot Integration Test Report

-`); + + +const logStream = reportingForTests(); + // Overriding the default 10 sec. timeout and setting it to 60 sec. before(async function () { if (aibEndPoint === undefined) throw new Error("Endpoint is not defined. Test will fail intentionally."); this.timeout(120000); - const apiToken = await getIntelligenceAPIAccessToken(); - accessToken = apiToken.accessToken; + accessToken = await getAccessToken(); + // Write heading and table headers to the HTML file - writeHeading(logStream, `${AIB_ENDPOINT}`); - writeTableHeaders(logStream); + await writeHeadingandTableHeaders(logStream); }); // Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write code to add 'Account' entity form to my webpage 'html' with some section code."; - it(testName, async () => { - const testStartTime = new Date(); - - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - "","adx_webpage","adx_copy","html","" - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\web-pages\\html\\content-pages\\Html.en-US.webpage.copy.html', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); - - console.log('Launch browser and navigate to run time'); - const page = await LaunchRunTime('Html'); - - await page.waitForSelector('[aria-label="Basic Form"]', {timeout: 60000}); - await expect(page.locator('[aria-label="Basic Form"]')).toBeVisible(); - await page.close(); - - // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); - }); - - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write code to add a button with name Test which should redirect to microsoft.com url"; - it(testName, async () => { - const testStartTime = new Date(); - - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - "","adx_webpage","adx_copy","html","" - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\web-pages\\html\\content-pages\\Html.en-US.webpage.copy.html', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); - - console.log('Launch browser and navigate to run time'); - const browser = await chromium.launch({ headless: false }); // Set headless: false to see the browser UI - const page = await browser.newPage(); - await page.waitForTimeout(20000); - - await page.goto('https://site-ej93f.powerappsportals.com/Html/',{timeout:60000}); - await page.waitForLoadState(); - await page.waitForLoadState('domcontentloaded'); - - const url=await page.locator("//button[text()='Test']").getAttribute('onclick'); - await expect(url).toContain('microsft.com'); +describe('Copilot Html and Css integration tests', async function () { + it(HtmlQueries.Query1, async () => { + const testName = HtmlQueries.Query1; + const testStartTime = new Date(); + + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "","adx_webpage","adx_copy","html","" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.HtmlWebpageCopy, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); + + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('Html', true); + + await page.waitForSelector(FormConstants.BasicForm, {timeout: 60000}); + await expect(page.locator(FormConstants.BasicForm)).toBeVisible(); + await page.close(); + + // Record end time after test execution + reportAfterTestCompletes(testName,testStartTime,response,logStream); + }).timeout(120000); + + it(HtmlQueries.Query2,async () => { + const testName = HtmlQueries.Query2; + const testStartTime = new Date(); + + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "","adx_webpage","adx_copy","html","" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.HtmlWebpageCopy, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); + + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('Html', true); + + const url = await page.locator(PageConstants.TestButton).getAttribute('onclick'); + expect(url).toContain('microsft.com'); + + await page.click(PageConstants.TestButton); + expect(page.url()).toBe(TextConstants.MicrosoftURL); + await page.close(); + + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); - await page.click("//button[text()='Test']"); - await expect(page.url()).toBe('https://www.microsoft.com/en-in/'); - await page.close(); - - // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); - }); - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write html code to add an image for microsoft and choose image from online"; - it(testName, async () => { - const testStartTime = new Date(); - - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - "","adx_webpage","adx_copy","html","" - ]; + it(HtmlQueries.Query3, async () => { + const testStartTime = new Date(); + const testName = HtmlQueries.Query3; + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "","adx_webpage","adx_copy","html","" + ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Record end time after test execution - const testEndTime = new Date(); + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\web-pages\\html\\content-pages\\Html.en-US.webpage.copy.html', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.HtmlWebpageCopy, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const browser = await chromium.launch({ headless: false }); // Set headless: false to see the browser UI - const page = await browser.newPage(); - await page.waitForTimeout(20000); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('Html', true); - await page.goto('https://site-ej93f.powerappsportals.com/Html/',{timeout:60000}); - await page.waitForLoadState(); - await page.waitForLoadState('domcontentloaded'); - - await page.waitForSelector('img[alt="Microsoft Logo"]', {timeout: 60000}); - await expect(page.locator('img[alt="Microsoft Logo"]')).toBeVisible(); + await page.waitForSelector(PageConstants.MicrosoftLogo, {timeout: 60000}); + await expect(page.locator(PageConstants.MicrosoftLogo)).toBeVisible(); + await page.close(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); - }).timeout(120000); - }); + }).timeout(120000); - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write css code to change the first section color of home page to yellow"; - it.skip(testName, async () => { - const testStartTime = new Date(); - - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + it(CssQueries.Query1, async () => { + const testStartTime = new Date(); + const testName = CssQueries.Query1; + + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\web-pages\\home\\content-pages\\Home.en-US.webpage.custom_css.css', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.HomePageCss, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const browser = await chromium.launch({ headless: false }); // Set headless: false to see the browser UI - const context = await browser.newContext({ - // Disable cache - bypassCSP: true, - }); - const page = await context.newPage(); - await page.waitForTimeout(20000); - await page.goto('https://site-ej93f.powerappsportals.com/',{timeout:60000}); - await page.waitForLoadState(); - await page.waitForLoadState('domcontentloaded'); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('Home', true); - const row = await page.locator('.sectionBlockLayout:first-of-type').first(); - const backgroundColor = await row.evaluate((element) => { - return window.getComputedStyle(element).backgroundColor; - }); - expect(backgroundColor.toString()).toContain('rgb(255, 255, 0)'); - await page.close(); - - // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - }).timeout(120000); - }); + const row = await page.locator(PageConstants.Section).first(); + const backgroundColor = await row.evaluate((element) => { + return window.getComputedStyle(element).backgroundColor; + }); + expect(backgroundColor.toString()).toContain(PageConstants.YellowColor); + await page.close(); - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write css code to change first existing button background color to red"; - it(testName, async () => { - const testStartTime = new Date(); - - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); + + it(CssQueries.Query2, async () => { + const testStartTime = new Date(); + const testName = CssQueries.Query2; + + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\web-pages\\home\\content-pages\\Home.en-US.webpage.custom_css.css', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.HomePageCss, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const browser = await chromium.launch({ headless: false }); // Set headless: false to see the browser UI - const page = await browser.newPage(); - await page.waitForTimeout(20000); - await page.goto('https://site-ej93f.powerappsportals.com/',{timeout:60000}); - await page.waitForLoadState(); - await page.waitForLoadState('domcontentloaded'); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('Home',true); - const button = await page.locator('[class="button1"]').first(); - const backgroundColor = await button.evaluate((element) => { - return window.getComputedStyle(element).backgroundColor; - }); - expect(backgroundColor.toString()).toContain('rgb(255, 0, 0)'); - await page.close(); + const button = page.locator(PageConstants.Button1).first(); + const backgroundColor = await button.evaluate((element) => { + return window.getComputedStyle(element).backgroundColor; + }); + expect(backgroundColor.toString()).toContain(PageConstants.RedColor); + await page.close(); - // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - }).timeout(120000); - }); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write css code to change button text to italic for all buttons"; - it(testName, async () => { - const testStartTime = new Date(); + it(CssQueries.Query3, async () => { + const testStartTime = new Date(); + const testName = CssQueries.Query3; - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\web-pages\\home\\content-pages\\Home.en-US.webpage.custom_css.css', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.HomePageCss, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const browser = await chromium.launch({ headless: false }); // Set headless: false to see the browser UI - const page = await browser.newPage(); - await page.waitForTimeout(20000); - await page.goto('https://site-ej93f.powerappsportals.com/',{timeout:60000}); - await page.waitForLoadState(); - await page.waitForLoadState('domcontentloaded'); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('Home',true); - const buttons = await page.$$('[type="button"][class*="button"]'); - for (const selector of buttons) { - const fontStyle = await selector?.evaluate((element) => { - return window.getComputedStyle(element).fontStyle; - }); - expect(fontStyle.toString()).toBe('italic'); - } - await page.close(); - - // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - }).timeout(120000); - }); + const buttons = await page.$$(PageConstants.Button); + for (const selector of buttons) { + const fontStyle = await selector?.evaluate((element) => { + return window.getComputedStyle(element).fontStyle; + }); + expect(fontStyle.toString()).toBe(TextConstants.Italic); + } + await page.close(); - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write css code to update first existing button background color to green important on hover"; - it(testName, async () => { - const testStartTime = new Date(); - - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + // Record end time after test execution + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); + + it(CssQueries.Query4, async () => { + const testStartTime = new Date(); + const testName = CssQueries.Query4; + + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\web-pages\\home\\content-pages\\Home.en-US.webpage.custom_css.css', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.HomePageCss, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const browser = await chromium.launch({ headless: false }); // Set headless: false to see the browser UI - const page = await browser.newPage(); - await page.waitForTimeout(20000); - await page.goto('https://site-ej93f.powerappsportals.com/',{timeout:60000}); - await page.waitForLoadState(); - await page.waitForLoadState('domcontentloaded'); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('Home',true); - const button = await page.locator('[class="button1"]').first(); - await button.hover(); - await page.waitForTimeout(5000); - const backgroundColor = await button.evaluate((element) => { - return window.getComputedStyle(element).backgroundColor; - }); - expect(backgroundColor.toString()).toContain('rgb(0, 128, 0)'); - await page.close(); + const button = page.locator(PageConstants.Button1).first(); + await button.hover(); + await page.waitForTimeout(5000); + const backgroundColor = await button.evaluate((element) => { + return window.getComputedStyle(element).backgroundColor; + }); + expect(backgroundColor.toString()).toContain(PageConstants.GreenColor); + await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - }).timeout(120000); - }); + reportAfterTestCompletes(testName, testStartTime, response, logStream); + }).timeout(120000); +}); // Close the HTML file with closing tags after all asynchronous code has completed // Assuming your tests are using Promises, you can return a Promise from your test diff --git a/src/web/client/test/integration/copilotPromptsValidationList.test.ts b/src/web/client/test/integration/copilotPromptsValidationList.test.ts index a98222ac1..ceb24bf54 100644 --- a/src/web/client/test/integration/copilotPromptsValidationList.test.ts +++ b/src/web/client/test/integration/copilotPromptsValidationList.test.ts @@ -3,110 +3,31 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { AIB_ENDPOINT, CreateAndExecuteAPIRequest, getIntelligenceAPIAccessToken, log, ITestLogParams, getFormattedDateTime, writeHeading, writeTableHeaders, closeHtmlFile, ReturnFormattedAPIResponse, LaunchRunTime, uploadPortal, verifyAPIResponse } from '../../utilities/copilotAutomationUtil'; +import { CreateAndExecuteAPIRequest, closeHtmlFile, ReturnFormattedAPIResponse, verifyAPIResponse, uploadPortal, LaunchRunTime, reportingForTests, reportAfterTestCompletes, getAccessToken, writeHeadingandTableHeaders } from '../../utilities/copilotAutomationUtil'; +import { AIB_ENDPOINT, ListConstants, ListQueries, PageConstants, Paths } from '../../common/constants'; const aibEndPoint = AIB_ENDPOINT; let accessToken : string; import fs from 'fs'; -import path from 'path'; import { expect } from 'playwright/test'; -const testReportPath = path.resolve(__dirname, `../test-reports`); // testReportPath => ..\powerplatform-vscode\out\web\client\test\test-reports -// Ensure the log directory exists -if (!fs.existsSync(testReportPath)) { - fs.mkdirSync(testReportPath); -} -const formattedDateTime = getFormattedDateTime(); -// Create a write stream to the HTML file -const logFilePath = path.join(testReportPath, `test-report-${formattedDateTime}.html`); -const logStream = fs.createWriteStream(logFilePath, { flags: 'w' }); -// Open the HTML file with initial structure -logStream.write(` - - - - Copilot Integration Test Report - - - -

Copilot Integration Test Report

-`); + +const logStream = reportingForTests(); // Overriding the default 10 sec. timeout and setting it to 60 sec. before(async function () { if (aibEndPoint === undefined) throw new Error("Endpoint is not defined. Test will fail intentionally."); this.timeout(120000); - const apiToken = await getIntelligenceAPIAccessToken(); - accessToken = apiToken.accessToken; + accessToken = await getAccessToken(); + // Write heading and table headers to the HTML file - writeHeading(logStream, `${AIB_ENDPOINT}`); - writeTableHeaders(logStream); + await writeHeadingandTableHeaders(logStream); }); + // Run tests for Copilot SUGGESTED prompts -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write JavaScript code to highlight the row where title column value is rf in table list."; - it(testName, async () => { +describe('Copilot List integration tests', async function () { + it(ListQueries.Query1, async () => { const testStartTime = new Date(); - + const testName = ListQueries.Query1; + // Actual values to replace placeholders from API request JSON. const actualValues = [ testName, // question @@ -116,97 +37,73 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\lists\\Active-Feedback.list.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.ListJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); const page = await LaunchRunTime('List'); - const row=await page.locator('tr[data-name="rf"]'); + const row = page.locator(ListConstants.DataRecord); const backgroundColor = await row.evaluate((element) => { return window.getComputedStyle(element).backgroundColor; }); - expect(backgroundColor.toString()).toContain('rgb(255, 255, 0)'); - + expect(backgroundColor.toString()).toContain(PageConstants.YellowColor); await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); + reportAfterTestCompletes(testName,testStartTime,response,logStream); }).timeout(120000); -}); -describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "Write javascript code to Mark rows with amount > 500 with yellow and amount datatype is dollars"; - it(testName, async () => { - const testStartTime = new Date(); + + it(ListQueries.Query2, async () => { + const testStartTime = new Date(); + const testName = ListQueries.Query2 ; - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - "cr1ae_amount","adx_entitylist","","","feedback" - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "cr1ae_amount","adx_entitylist","","","feedback" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\lists\\Active-Feedback.list.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.ListJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const page = await LaunchRunTime('List'); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('List'); - const elements=await page.$$('[data-attribute="cr1ae_amount"]'); + const elements=await page.$$(ListConstants.AmountColumn); for (const element of elements) { const textContent = await element.innerText(); const amountValue=parseFloat(textContent.split('$')[1]); if(amountValue>500){ - const backgroundColor = await element.evaluate((element1) => { - return window.getComputedStyle(element1).backgroundColor; - }); - - expect(backgroundColor.toString()).toContain('rgb(255, 255, 0)'); + const backgroundColor = await element.evaluate((element1) => { + return window.getComputedStyle(element1).backgroundColor; + }); + expect(backgroundColor.toString()).toContain(PageConstants.YellowColor); } } + await page.close(); - await page.close(); - // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); - }); - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "write javascript code to arrange amount column values in descending order"; - it(testName, async () => { - const testStartTime = new Date(); + // Record end time after test execution + reportAfterTestCompletes(testName,testStartTime,response,logStream); + }).timeout(120000); + + it(ListQueries.Query3, async () => { + const testStartTime = new Date(); + const testName = ListQueries.Query3; - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - "cr1ae_amount","adx_entitylist","","","feedback" - ]; - - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "cr1ae_amount","adx_entitylist","","","feedback" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response + // Assert API response await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\lists\\Active-Feedback.list.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + fs.writeFileSync(Paths.ListJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); await uploadPortal(); console.log('Launch browser and navigate to run time'); @@ -223,63 +120,42 @@ describe('Copilot SUGGESTED prompts integration tests', async function () { await page.close(); // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); - }); - describe('Copilot SUGGESTED prompts integration tests', async function () { - const testName = "write javascript code to arrange amount column values in ascending order"; - it(testName, async () => { - const testStartTime = new Date(); + reportAfterTestCompletes(testName,testStartTime,response,logStream); + }).timeout(120000); + + it(ListQueries.Query4, async () => { + const testStartTime = new Date(); + const testName = ListQueries.Query4; - // Actual values to replace placeholders from API request JSON. - const actualValues = [ - testName, // question - "cr1ae_amount","adx_entitylist","","","feedback" - ]; - const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); + // Actual values to replace placeholders from API request JSON. + const actualValues = [ + testName, // question + "cr1ae_amount","adx_entitylist","","","feedback" + ]; + const response = await CreateAndExecuteAPIRequest(testName, actualValues, accessToken, logStream); - // Assert API response - await verifyAPIResponse(response); - fs.writeFileSync('C:\\Users\\v-ankopuri\\Downloads\\CopilotSiteLatest\\latest-site-for-copilot---site-ej93f\\lists\\Active-Feedback.list.custom_javascript.js', ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); - await uploadPortal(); + // Assert API response + await verifyAPIResponse(response); + fs.writeFileSync(Paths.ListJsFile, ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response[0].code)); + await uploadPortal(); - console.log('Launch browser and navigate to run time'); - const page = await LaunchRunTime('List'); + console.log('Launch browser and navigate to run time'); + const page = await LaunchRunTime('List'); - const amounts = await page.evaluate(() => { - const elements = document.querySelectorAll('[data-attribute="cr1ae_amount"]'); - return Array.from(elements).map(el => el.textContent || '').map(text => parseFloat(text.replace('$', '').trim())); - }); - // Check if amounts are in ascending order - const isAscending = amounts.every((value, index, array) => index === 0 || value >= array[index - 1]); - expect(isAscending).toBeTruthy(); + const amounts = await page.evaluate(() => { + const elements = document.querySelectorAll('[data-attribute="cr1ae_amount"]'); + return Array.from(elements).map(el => el.textContent || '').map(text => parseFloat(text.replace('$', '').trim())); + }); - await page.close(); + // Check if amounts are in ascending order + const isAscending = amounts.every((value, index, array) => index === 0 || value >= array[index - 1]); + expect(isAscending).toBeTruthy(); + await page.close(); - // Record end time after test execution - const testEndTime = new Date(); - const testLogParams: ITestLogParams = { - testName: testName, - testStartTime: testStartTime, - testEndTime: testEndTime, - actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), - status: 'PASSED', - logStream: logStream - } - log(testLogParams); - - }).timeout(120000); - }); + // Record end time after test execution + reportAfterTestCompletes(testName,testStartTime,response,logStream); + }).timeout(120000); +}); // Close the HTML file with closing tags after all asynchronous code has completed // Assuming your tests are using Promises, you can return a Promise from your test diff --git a/src/web/client/utilities/copilotAutomationUtil.ts b/src/web/client/utilities/copilotAutomationUtil.ts index a381df559..8be113954 100644 --- a/src/web/client/utilities/copilotAutomationUtil.ts +++ b/src/web/client/utilities/copilotAutomationUtil.ts @@ -3,41 +3,25 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ + import * as vscode from 'vscode'; import axios from 'axios'; import { INTELLIGENCE_SCOPE_DEFAULT, PROVIDER_ID } from "../../../common/services/Constants"; import { ERROR_CONSTANTS } from "../../../common/ErrorConstants"; import * as https from 'https' -import { EXTENSION_NAME } from "../../../common/constants" -import { getExtensionVersion } from '../../../common/utilities/Utils'; import fs from 'fs'; import { promisify } from 'util'; import { exec } from 'child_process'; import { chromium } from 'playwright'; import * as chai from 'chai'; +import path from 'path'; +import { AIB_ENDPOINT, ApiRequestJson, ExpectedResponses } from '../common/constants'; +import { IApiRequestParams, ITestLogParams } from '../common/interfaces'; const chaiExpect = chai.expect; const violationOrUnclearResponseCodes : string[] = ["violation", "unclear", "unsupported"]; -// export const AIB_ENDPOINT = 'YOUR_API_ENDPOINT_HERE'; - -export const AIB_ENDPOINT = 'https://aibuildertextapiservice.us-il108.gateway.prod.island.powerapps.com/v1.0/09c165e4-df13-ef11-9f83-000d3a342d10/appintelligence/chat' -// 'https://aibuildertextapiservice.us-il109.gateway.Prod.island.powerapps.com/v1.0/63efacda-3db4-ee11-a564-000d3a106f1e/appintelligence/chat'; - -export interface IApiRequestParams { - aibEndPoint: string; - apiToken: string; - data: unknown; -} - -export interface ITestLogParams { - testName: string, - testStartTime: Date, - testEndTime: Date, - actualResponse: string, - status: string, - logStream: fs.WriteStream -} - // // Function to get the access token for the API // @@ -62,29 +46,6 @@ export async function getIntelligenceAPIAccessToken() : Promise<{ accessToken: s return { accessToken }; } -// JSON request to be sent to the API. -export const ApiRequestJson = { - "question": "{0}", - "top": 1, - "context": - { - "scenario": "PowerPagesProDev", - "subScenario": "PowerPagesProDevGeneric", - "version": "V1", - "information": - { - "activeFileContent": "{6}", - "dataverseEntity": "{2}", - "entityField": "{3}", - "fieldType": "{4}", - "targetEntity": "{5}", - "targetColumns": "{1}", // Placeholder value for targetColumns - "clientType": EXTENSION_NAME + '-' + 'Desktop', - "clientVersion": getExtensionVersion() - } - } -}; - // // Function to replace the placeholders in the JSON request with actual values // Replace placeholders with actual values. We can pass more comma separated values matching the placeholders from request json. @@ -297,23 +258,10 @@ export function ReturnFormattedAPIResponse(responseData : []) { return appendedString; } -export const ExpectedResponses = { - COPILOT_IT_UNSUPPORTED_EXPECTED_RESPONSE: { - "displayText":"Try a different prompt that’s related to writing code for Power Pages sites. You can get help with HTML, CSS, and JS languages.", - "Code":"violation", - "language":"text", - "useCase":"unsupported" - } -}; - -export const SuggestedPromptsConstants : Record = { - Name: "Write javascript code to validate name field to not accept special characters", - Subject: "Write javascript code to validate subject field to not accept special characters", -} - export const formatString = (str: string, ...args: string[] | number[]) => str.replace(/{(\d+)}/g, (match, index) => args[index].toString() || ''); + export async function verifyAPIResponse(response:any) { chaiExpect(response).to.have.property('status'); chaiExpect(response.status).to.equal(200); @@ -337,17 +285,136 @@ export async function uploadPortal(){ cwd: 'C:\\Users\\v-ankopuri\\AppData\\Local\\Microsoft\\PowerAppsCli', }; const execAsync = promisify(exec); - const { stdout, stderr } = await execAsync('pac paportal upload -p C:/Users/v-ankopuri/Downloads/CopilotSiteLatest/latest-site-for-copilot---site-ej93f -mv 2',options); + const { stdout, stderr } = await execAsync('pac paportal upload -p C:/Users/v-ankopuri/Downloads/CopilotSiteLatest/latest-site-for-copilot---site-uo67k -mv 2',options); chaiExpect(stdout.trim()).to.contain('Power Pages website upload succeeded'); chaiExpect(stderr).to.be.empty; } -export async function LaunchRunTime(pageName:string){ +export async function LaunchRunTime(pageName:string, timeout = false){ const browser = await chromium.launch({ headless: false }); // Set headless: false to see the browser UI const page = await browser.newPage(); - - await page.goto(formatString('https://site-ej93f.powerappsportals.com/{0}/',pageName),{timeout:60000}); + if(timeout){ + await page.waitForTimeout(20000); + } + if(pageName == 'Home'){ + await page.goto('https://site-uo67k.powerappsportals.com/',{timeout:60000}); + } + else{ + await page.goto(formatString('https://site-uo67k.powerappsportals.com/{0}/',pageName),{timeout:60000}); + } + await page.waitForLoadState(); await page.waitForLoadState('domcontentloaded'); return page; -} \ No newline at end of file +} + +export function reportingForTests(){ + const testReportPath = path.resolve(__dirname, `../test-reports`); // testReportPath => ..\powerplatform-vscode\out\web\client\test\test-reports +// Ensure the log directory exists +if (!fs.existsSync(testReportPath)) { + fs.mkdirSync(testReportPath); +} +const formattedDateTime = getFormattedDateTime(); +// Create a write stream to the HTML file +const logFilePath = path.join(testReportPath, `test-report-${formattedDateTime}.html`); +const logStream = fs.createWriteStream(logFilePath, { flags: 'w' }); +// Open the HTML file with initial structure +logStream.write(` + + + + Copilot Integration Test Report + + + +

Copilot Integration Test Report

+`); +return logStream; +} + +export async function reportAfterTestCompletes(testName:string,testStartTime: Date,response : any,logStream: fs.WriteStream) { + // Record end time after test execution + const testEndTime = new Date(); + const testLogParams: ITestLogParams = { + testName: testName, + testStartTime: testStartTime, + testEndTime: testEndTime, + actualResponse: ReturnFormattedAPIResponse(response.data.additionalData[0].properties.response), + status: 'PASSED', + logStream: logStream + } + log(testLogParams); +} + +export async function getAccessToken() { + const apiToken = await getIntelligenceAPIAccessToken(); + return apiToken.accessToken; +} + +export async function writeHeadingandTableHeaders(logStream:fs.WriteStream) { + writeHeading(logStream, `${AIB_ENDPOINT}`); + writeTableHeaders(logStream); +} + +export { AIB_ENDPOINT, ITestLogParams };