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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions e2etests/mocks/recommendation-card-metadata.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,12 @@ export const getCardMetaData = (recommendationsPage: RecommendationsPage): CardM
},
{
name: 'Resources With Insecure Security Groups Settings',
savingsValue: recommendationsPage.resourcesWithInsecureSecurityGroupsSettingsCardSavingsValue,
countValue: recommendationsPage.resourcesWithInsecureSecurityGroupsSettingsCountValue,
seeAllBtn: recommendationsPage.resourcesWithInsecureSecurityGroupsSettingsSeeAllBtn,
errorLocator: recommendationsPage.resourcesWithInsecureSecurityGroupsSettingsError,
tableLocator: recommendationsPage.resourcesWithInsecureSecurityGroupsSettingsTableSavingsValue,
modalColumnLocator: undefined, //TODO: Unable to determine which column this card uses without any savings data
},
{
name: 'Snapshots with non-used Images',
Expand Down
7 changes: 7 additions & 0 deletions e2etests/pages/recommendations-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,11 @@ export class RecommendationsPage extends BasePage {
readonly reservedInstancesOpportunitiesError: Locator;
readonly reservedInstancesOpportunitiesTableSavingsValue: Locator;

readonly resourcesWithInsecureSecurityGroupsSettingsCardSavingsValue: Locator;
readonly resourcesWithInsecureSecurityGroupsSettingsCountValue: Locator;
readonly resourcesWithInsecureSecurityGroupsSettingsSeeAllBtn: Locator;
readonly resourcesWithInsecureSecurityGroupsSettingsError: Locator;
readonly resourcesWithInsecureSecurityGroupsSettingsTableSavingsValue: Locator;

readonly publicS3BucketsCardSavingsValue: Locator;
readonly publicS3BucketsSeeAllBtn: Locator;
Expand All @@ -190,6 +192,8 @@ export class RecommendationsPage extends BasePage {
readonly snapshotsWithNonUsedImagesError: Locator;
readonly snapshotsWithNonUsedImagesTableSavingsValue: Locator;

readonly noRecommendationsMessage: Locator;

/**
* Initializes a new instance of the RecommendationsPage class.
* @param {Page} page - The Playwright page object.
Expand Down Expand Up @@ -239,6 +243,7 @@ export class RecommendationsPage extends BasePage {
this.searchInput = this.main.getByPlaceholder('Search');
this.cardsGrid = this.main.locator('//div[contains(@class, "cardsGrid MuiBox-root")]');
this.table = this.main.locator('table');
this.noRecommendationsMessage = this.main.getByText('No recommendations found');

// Data source icons
const brandConfigs = {
Expand Down Expand Up @@ -482,6 +487,7 @@ export class RecommendationsPage extends BasePage {
async getCurrencyValue(currencyLocator: Locator): Promise<number> {
await currencyLocator.scrollIntoViewIfNeeded();
const text = await currencyLocator.textContent();
debugLog(`getCurrencyValue raw text: "${text}"`);
return this.parseCurrencyValue(text);
}

Expand Down Expand Up @@ -522,6 +528,7 @@ export class RecommendationsPage extends BasePage {
{ label: 'Obsolete Snapshots', locator: this.obsoleteSnapshotsCardSavingsValue },
{ label: 'Obsolete Snapshot Chains', locator: this.obsoleteSnapshotChainsCardSavingsValue },
{ label: 'Reserved Instances Opportunities', locator: this.reservedInstancesOpportunitiesCardSavingsValue },
{ label: 'Resources with Insecure Security Groups settings', locator: this.resourcesWithInsecureSecurityGroupsSettingsTableSavingsValue },
{ label: 'Public S3 Buckets', locator: this.publicS3BucketsCardSavingsValue },
{ label: 'Snapshots With Non-used Images', locator: this.snapshotsWithNonUsedImagesCardSavingsValue },
{ label: 'Underutilized Instances', locator: this.underutilizedInstancesCardSavingsValue },
Expand Down
16 changes: 14 additions & 2 deletions e2etests/setup/auth.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { test as setup } from '@playwright/test';
import { getLocalforageRoot, injectLocalforage } from '../utils/auth-session-storage/localforage-service';
import { safeWriteJsonFile } from '../utils/file';
import { LiveDemoService } from '../utils/auth-session-storage/auth-helpers';
import { LARGE_DATA_TIMEOUT } from '../playwright.config';
import { debugLog, errorLog } from '../utils/debug-logging';

const useLiveDemoCredentials = LiveDemoService.shouldUseLiveDemo();

Expand Down Expand Up @@ -40,8 +42,18 @@ setup.describe('Auth Setup', () => {
await page.getByTestId('input_pass').fill(password);
await page.getByTestId('btn_login').click();
const initializingMessage = page.getByTestId('p_initializing')
await initializingMessage.waitFor({ timeout: 20000 });
await initializingMessage.waitFor({ state: 'detached', timeout: 20000 });
try {
await initializingMessage.first().waitFor({ timeout: 1000 });
} catch (_error) {
// Exit the method if the initialisation message is not present.
return;
}
try {
debugLog('Waiting for initialisaton message to disappear...');
await initializingMessage.waitFor({ state: 'hidden', timeout: LARGE_DATA_TIMEOUT });
} catch (_error) {
errorLog('[ERROR] initialisaton message did not disappear within the timeout.');
}
const loadingImage = page.getByRole('img', { name: 'Loading page' });
await loadingImage.waitFor();
await loadingImage.waitFor({ state: 'detached', timeout: 20000 });
Expand Down
11 changes: 10 additions & 1 deletion e2etests/tests/homepage-tests.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable playwright/no-conditional-in-test, playwright/no-conditional-expect */
import { test } from '../fixtures/page.fixture';
import { expect } from '@playwright/test';
import { isWithinRoundingDrift } from '../utils/custom-assertions';
import { InterceptionEntry } from '../types/interceptor.types';
import { OrganisationConstraintsMock } from '../mocks/home-page.mocks';
import { debugLog } from '../utils/debug-logging';

test.describe('[MPT-11464] Home Page Recommendations block tests', { tag: ['@ui', '@recommendations', '@homepage'] }, () => {
test.describe.configure({ mode: 'default' });
Expand Down Expand Up @@ -48,13 +50,19 @@ test.describe('[MPT-11464] Home Page Recommendations block tests', { tag: ['@ui'
expect.soft(await recommendationsPage.getTotalSumOfItemsFromSeeItemsButtons()).toBe(homePageValue);
});

// Test failing due to bug MPT-11558 The home page recommendations block not returning the real Critical item count
test('[230553] Verify Critical items displayed in the recommendations block match the sum total of items displayed on cards with the critical status', async ({
homePage,
recommendationsPage,
}) => {
const homePageValue = await homePage.getRecommendationsCriticalValue();
await homePage.recommendationsCriticalLink.click();

if(homePageValue === 0){
debugLog('No critical recommendations, verifying that the no recommendations message is shown');
await expect(recommendationsPage.noRecommendationsMessage).toBeVisible();
return;
}

expect.soft(await recommendationsPage.selectedComboBoxOption(recommendationsPage.categoriesSelect)).toEqual('Critical');
expect.soft(await recommendationsPage.getTotalSumOfItemsFromSeeItemsButtons()).toBe(homePageValue);
});
Expand Down Expand Up @@ -186,6 +194,7 @@ test.describe('[MPT-12743] Home Page test for Pools requiring attention block',
const limitValue = Math.round(expenseValue - 1);
await poolsPage.toggleExpandPool();
subPoolExpenseValue = await poolsPage.getSubPoolExpensesThisMonth(1);
test.skip(subPoolExpenseValue <= 1, 'Sub-pool expenses are too low to set a limit below them and still have a positive limit value');
const subPoolLimitValue = Math.round(subPoolExpenseValue - 1);
await poolsPage.editSubPoolMonthlyLimit(subPoolLimitValue, true, 1);
await poolsPage.editPoolMonthlyLimit(limitValue);
Expand Down
14 changes: 8 additions & 6 deletions e2etests/tests/perspective-tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ test.describe('[MPT-18579] Perspective Tests', { tag: ['@ui', '@resources', '@pe
test.describe.configure({ mode: 'default' });
test.use({ restoreSession: true });
test.slow();
const env = process.env.ENVIRONMENT.toLowerCase();

test('[232963] User can create an Expenses perspective and the chart options are saved and applied correctly', async ({
resourcesPage,
Expand All @@ -16,9 +17,9 @@ test.describe('[MPT-18579] Perspective Tests', { tag: ['@ui', '@resources', '@pe
await resourcesPage.navigateToResourcesPageAndResetFilters();

const filter = 'Region';
const filterOption = 'East US';
const filterOption = env !== 'test' ? 'eu-west-1' : 'West Europe';
const categorizeBy = 'Resource type';
const groupByTag = 'costcenter';
const groupByTag = env !== 'test' ? 'Component' : 'devops-component';
const perspectiveName = `Test Perspective ${new Date().getTime()}`;

await test.step('Select options to save as a perspective', async () => {
Expand Down Expand Up @@ -128,7 +129,7 @@ test.describe('[MPT-18579] Perspective Tests', { tag: ['@ui', '@resources', '@pe
await resourcesPage.navigateToResourcesPageAndResetFilters();

const filter = 'Pool';
const filterOption = 'Marketplace (Dev)';
const filterOption = env !== 'test' ? 'Marketplace (Staging)' : 'Marketplace (Test)';
const perspectiveName = `Test Perspective ${new Date().getTime()}`;

await test.step('Select options to save as a perspective', async () => {
Expand Down Expand Up @@ -206,6 +207,7 @@ test.describe('[MPT-18579] Perspective Tests', { tag: ['@ui', '@resources', '@pe
});

test('[232967] User can create a perspective and delete it via the perspectives table', async ({ resourcesPage, perspectivesPage }) => {
const tag= env !== 'test' ? 'Component' : 'devops-component';
await perspectivesPage.navigateToURL();
const initialPerspectivesCount = await perspectivesPage.getPerspectivesCount();
debugLog(`Initial perspectives count: ${initialPerspectivesCount}`);
Expand All @@ -216,7 +218,7 @@ test.describe('[MPT-18579] Perspective Tests', { tag: ['@ui', '@resources', '@pe

await test.step('Create and save a perspective', async () => {
await resourcesPage.clickExpensesTab();
await resourcesPage.selectGroupByTag('environment');
await resourcesPage.selectGroupByTag(tag);
await resourcesPage.click(resourcesPage.savePerspectiveBtn);
await resourcesPage.savePerspective(perspectiveName);
});
Expand Down Expand Up @@ -247,7 +249,7 @@ test.describe('[MPT-18579] Perspective Tests', { tag: ['@ui', '@resources', '@pe
await resourcesPage.navigateToResourcesPageAndResetFilters();

const filter1 = 'Region';
const filterOption1 = 'West Europe';
const filterOption1 = env !== 'test' ? 'eu-west-1' : 'West Europe';
const filter2 = 'Recommendations';
const filterOption2 = 'With recommendations';
const perspectiveName = `Test Perspective ${new Date().getTime()}`;
Expand Down Expand Up @@ -290,7 +292,7 @@ test.describe('[MPT-18579] Perspective Tests', { tag: ['@ui', '@resources', '@pe
await resourcesPage.navigateToResourcesPageAndResetFilters();

const filter1 = 'Region';
const filterOption1 = 'West Europe';
const filterOption1 = env !== 'test' ? 'eu-west-1' : 'West Europe';
const filter2 = 'Recommendations';
const filterOption2 = 'With recommendations';
const perspectiveName = `Test Perspective ${new Date().getTime()}`;
Expand Down
14 changes: 6 additions & 8 deletions e2etests/tests/policies-tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,12 @@ test.describe('[MPT-16366] Policies Tests', { tag: ['@ui', '@policies'] }, () =>
});

test('[232287] Verify that user can add a resource quota policy', async ({ policiesPage, policiesCreatePage }) => {
const NBSP = '\u00A0'
const env = process.env.ENVIRONMENT.toLowerCase();
const policyName = `Resource Policy ${Date.now()}`;
const resourceCount = 10;
const filterOption = 'West Europe';
const filterData = `Region:${NBSP}.a{fill:url(#a);}
.b{fill:#0078d4;}
.c{fill:url(#b);}
.d{fill:url(#c);} ${filterOption}`;
// eslint-disable-next-line playwright/no-conditional-in-test
const filterOption = env !== 'test' ? 'eu-west-1' : 'West Europe';


await test.step('Create Resource Policy', async () => {
await policiesPage.navigateToCreatePolicy();
Expand All @@ -80,7 +78,7 @@ test.describe('[MPT-16366] Policies Tests', { tag: ['@ui', '@policies'] }, () =>

await expect.soft(targetPolicyRow.locator('xpath=/td[1]')).toHaveText(policyName);
await expect.soft(targetPolicyRow.locator('xpath=/td[3]')).toHaveText(`Resource count must not exceed ${resourceCount}.`);
await expect.soft(targetPolicyRow.locator('xpath=/td[4]')).toContainText(filterData);
await expect.soft(targetPolicyRow.locator('xpath=/td[4]')).toContainText(filterOption);
});

await test.step('Navigate to the created policy details page', async () => {
Expand All @@ -92,7 +90,7 @@ test.describe('[MPT-16366] Policies Tests', { tag: ['@ui', '@policies'] }, () =>
await expect.soft(policiesPage.policyDetailsDiv).toContainText(`Name: ${policyName}`);
await expect.soft(policiesPage.policyDetailsDiv).toContainText('Type: Resource quota');
await expect.soft(policiesPage.policyDetailsDiv).toContainText(`Resource count: ${resourceCount}`);
await expect.soft(policiesPage.policyDetailsDiv).toContainText(`${filterData}`);
await expect.soft(policiesPage.policyDetailsDiv).toContainText(`${filterOption}`);
});
});

Expand Down
7 changes: 6 additions & 1 deletion e2etests/tests/recommendations-tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ test.describe('[MPT-11310] Recommendations page tests', { tag: ['@ui', '@recomme
});

test('[230597] Verify Data Source selection works correctly', async ({ recommendationsPage }) => {
const dataSource = process.env.USE_LIVE_DEMO === 'true' ? 'Azure QA' : 'CPA (Development and Test)';
const dataSource = process.env.USE_LIVE_DEMO === 'true' ? 'Azure QA' : 'Marketplace (Dev)';

await test.step(`Select data source: ${dataSource}`, async () => {
await recommendationsPage.selectDataSource(dataSource);
Expand Down Expand Up @@ -293,6 +293,8 @@ test.describe('[MPT-11310] Recommendations page tests', { tag: ['@ui', '@recomme

await test.step('Select Critical category and verify every card has a critical icon', async () => {
await recommendationsPage.selectCategory('Critical');
test.skip(await recommendationsPage.noRecommendationsMessage.isVisible(), 'No recommendations are marked as Critical');

await recommendationsPage.allCardHeadings.last().waitFor();
count = await recommendationsPage.allCardHeadings.count();
actualHeadings = await recommendationsPage.allCardHeadings.allTextContents();
Expand Down Expand Up @@ -439,8 +441,11 @@ test.describe('[MPT-11310] Recommendations page tests', { tag: ['@ui', '@recomme
let cardSavings = undefined;
let cardCount = undefined;

debugLog(`${cardName} savingsValue defined: ${!!savingsValue}`);
if (savingsValue) {
cardSavings = await recommendationsPage.getCurrencyValue(savingsValue);
debugLog(`${cardName} Card Savings Value: ${cardSavings}`);


if (cardSavings === 0) {
const value = await savingsValue.textContent();
Expand Down
16 changes: 11 additions & 5 deletions e2etests/tests/tagging-policy-tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ async function deleteAllPolicies() {
test.describe('[MPT-17042] Tagging Policy Tests', { tag: ['@ui', '@tagging-policies'] }, () => {
test.describe.configure({ mode: 'default' });
test.use({ restoreSession: true });
const env = process.env.ENVIRONMENT.toLowerCase();

test.beforeEach('Login admin user', async ({ taggingPoliciesPage }) => {
await test.step('Login admin user', async () => {
Expand All @@ -48,7 +49,8 @@ test.describe('[MPT-17042] Tagging Policy Tests', { tag: ['@ui', '@tagging-polic

test('[232656] Verify that a user can create a required tagging policy', async ({ taggingPoliciesPage, taggingPoliciesCreatePage }) => {
const policyName = `Required Tag Policy ${Date.now()}`;
const tagName = 'AccountId';
// eslint-disable-next-line playwright/no-conditional-in-test
const tagName = env !== 'test' ? 'Component' : 'devops-component';

await test.step('Create required Tagging Policy page', async () => {
await taggingPoliciesPage.navigateToCreateTaggingPolicy();
Expand All @@ -68,7 +70,8 @@ test.describe('[MPT-17042] Tagging Policy Tests', { tag: ['@ui', '@tagging-polic

test('[232657] Verify that a user can create a prohibited tagging policy', async ({ taggingPoliciesPage, taggingPoliciesCreatePage }) => {
const policyName = `Prohibited Tag Policy ${Date.now()}`;
const tagName = '__department';
// eslint-disable-next-line playwright/no-conditional-in-test
const tagName = env !== 'test' ? 'Component' : 'devops-component';
const filter = 'Activity';
const filterOption = 'Active';

Expand Down Expand Up @@ -101,8 +104,10 @@ test.describe('[MPT-17042] Tagging Policy Tests', { tag: ['@ui', '@tagging-polic
taggingPoliciesCreatePage,
}) => {
const policyName = `Correlated Tag Policy ${Date.now()}`;
const tagName = 'Instance';
const secondaryTagName = 'Environment';
// eslint-disable-next-line playwright/no-conditional-in-test
const tagName = env !== 'test' ? 'Component' : 'devops-component';
// eslint-disable-next-line playwright/no-conditional-in-test
const secondaryTagName = env !== 'test' ? 'aws:backup:source-resource' : 'CostCenter';

await test.step('Create tags correlation Tagging Policy page', async () => {
await taggingPoliciesPage.navigateToCreateTaggingPolicy();
Expand All @@ -127,7 +132,8 @@ test.describe('[MPT-17042] Tagging Policy Tests', { tag: ['@ui', '@tagging-polic
taggingPoliciesCreatePage,
}) => {
const policyName = `Policy To Be Deleted ${Date.now()}`;
const tagName = 'Application';
// eslint-disable-next-line playwright/no-conditional-in-test
const tagName = env !== 'test' ? 'Component' : 'devops-component';

await test.step('Create a policy to be deleted', async () => {
await taggingPoliciesPage.navigateToCreateTaggingPolicy();
Expand Down
Loading