Skip to content

Commit

Permalink
OZ-707: E2E tests verifying Odoo groups are synced to Keycloak.
Browse files Browse the repository at this point in the history
  • Loading branch information
kdaud committed Nov 4, 2024
1 parent 4b63cdf commit 0096de9
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 9 deletions.
126 changes: 124 additions & 2 deletions e2e/tests/keycloak-odoo-flows.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { test, expect } from '@playwright/test';
import { KEYCLOAK_URL, ODOO_URL } from '../utils/configs/globalSetup';
import { Odoo } from '../utils/functions/odoo';
import { Odoo, randomOdooGroupName } from '../utils/functions/odoo';
import { OpenMRS } from '../utils/functions/openmrs';
import { Keycloak } from '../utils/functions/keycloak';
import { KEYCLOAK_URL, ODOO_URL } from '../utils/configs/globalSetup';
import { randomSupersetRoleName } from '../utils/functions/superset';

let odoo: Odoo;
let openmrs: OpenMRS;
Expand Down Expand Up @@ -42,6 +43,127 @@ test('Logging out from Odoo logs out the user from Keycloak.', async ({ page })
await expect(page).toHaveURL(/.*login/);
});

test('Existing Odoo groups are synced as roles in Keycloak.', async ({ page }) => {
// setup
await page.goto(`${ODOO_URL}`);
await odoo.enterLoginCredentials();
await expect(page.locator('li.o_user_menu a span')).toHaveText(/administrator/i);
await odoo.activateDeveloperMode();

// replay
await odoo.navigateToGroups();
await expect(page.getByText('Administration / Settings')).toBeVisible();
await expect(page.getByText('Extra Rights / Technical Features')).toBeVisible();
await expect(page.getByText('Invoicing / Billing Administrator')).toBeVisible();
await expect(page.getByText('Technical / Discount on lines')).toBeVisible();
await expect(page.getByText('User types / Portal')).toBeVisible();

// verify
await keycloak.open();
await keycloak.navigateToClients();
await keycloak.selectOdooId();
await keycloak.selectRoles();
await page.getByPlaceholder('Search role by name').fill('Administration / Settings');
await page.getByRole('button', { name: 'Search' }).press('Enter');
await expect(page.getByText('Administration / Settings')).toBeVisible();
await page.getByPlaceholder('Search role by name').fill('Extra Rights / Technical Features');
await page.getByRole('button', { name: 'Search' }).press('Enter');
await expect(page.getByText('Extra Rights / Technical Features')).toBeVisible();
await page.getByPlaceholder('Search role by name').fill('Invoicing / Billing Administrator');
await page.getByRole('button', { name: 'Search' }).press('Enter');
await expect(page.getByText('Invoicing / Billing Administrator')).toBeVisible();
await page.getByPlaceholder('Search role by name').fill('Technical / Discount on lines');
await page.getByRole('button', { name: 'Search' }).press('Enter');
await expect(page.getByText('Technical / Discount on lines')).toBeVisible();
await page.getByPlaceholder('Search role by name').fill('User types / Portal');
await page.getByRole('button', { name: 'Search' }).press('Enter');
await expect(page.getByText('User types / Portal')).toBeVisible();
});

test('Creating an Odoo group creates the corresponding Keycloak role', async ({ page }) => {
// setup
await page.goto(`${ODOO_URL}`);
await odoo.enterLoginCredentials();
await expect(page.locator('li.o_user_menu a span')).toHaveText(/administrator/i);
await odoo.activateDeveloperMode();

// replay
await odoo.navigateToGroups();
await odoo.createGroup();

// verify
await keycloak.open();
await keycloak.navigateToClients();
await keycloak.selectOdooId();
await keycloak.selectRoles();
await keycloak.searchOdooRole();
await expect(page.locator('tbody:nth-child(2) td:nth-child(1) a')).toHaveText(`${randomOdooGroupName.groupName}`);
});
/*
test('Updating a synced Odoo group updates the corresponding Keycloak role.', async ({ page }) => {
// setup
await page.goto(`${ODOO_URL}`);
await odoo.enterLoginCredentials();
await expect(page.locator('li.o_user_menu a span')).toHaveText(/administrator/i);
await odoo.activateDeveloperMode();
await odoo.navigateToGroups();
await odoo.createGroup();
await keycloak.open();
await keycloak.navigateToClients();
await keycloak.selectOdooId();
await keycloak.selectRoles();
await keycloak.searchOdooRole();
await expect(page.locator('tbody:nth-child(2) td:nth-child(1) a')).toHaveText(`${randomOdooGroupName.groupName}`);
// replay
await page.goto(`${ODOO_URL}`);
await odoo.navigateToSettings();
await odoo.navigateToGroups();
await odoo.searchGroup();
await odoo.updateGroup();
// verify
await page.goto(`${KEYCLOAK_URL}/admin/master/console`);
await keycloak.navigateToClients();
await keycloak.selectOdooId();
await keycloak.selectRoles();
await keycloak.searchOdooRole();
await expect(page.getByText(`${randomSupersetRoleName.roleName}`)).not.toBeVisible();
await expect(page.getByText(`${randomSupersetRoleName.updatedRoleName}`)).toBeVisible();
});
test('Deleting a synced Odoo group deletes the corresponding Keycloak role.', async ({ page }) => {
// setup
await page.goto(`${ODOO_URL}`);
await odoo.enterLoginCredentials();
await expect(page.locator('li.o_user_menu a span')).toHaveText(/administrator/i);
await odoo.activateDeveloperMode();
await odoo.navigateToGroups();
await odoo.createGroup();
await keycloak.open();
await keycloak.navigateToClients();
await keycloak.selectOdooId();
await keycloak.selectRoles();
await keycloak.searchOdooRole();
await expect(page.locator('tbody:nth-child(2) td:nth-child(1) a')).toHaveText(`${randomOdooGroupName.groupName}`);
// replay
await page.goto(`${ODOO_URL}`);
await odoo.navigateToSettings();
await odoo.navigateToGroups();
await odoo.searchGroup();
await odoo.deleteGroup();
// verify
await page.goto(`${KEYCLOAK_URL}/admin/master/console`);
await keycloak.navigateToClients();
await keycloak.selectOdooId();
await keycloak.selectRoles();
await keycloak.searchOdooRole();
await expect(page.getByText(`${randomSupersetRoleName.roleName}`)).not.toBeVisible();
});
*/
test.afterEach(async ({ page }) => {
await page.close();
});
7 changes: 7 additions & 0 deletions e2e/utils/functions/keycloak.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Page, expect } from '@playwright/test';
import { KEYCLOAK_URL } from '../configs/globalSetup';
import { randomSupersetRoleName } from './superset';
import { delay, randomOpenMRSRoleName } from './openmrs';
import { randomOdooGroupName } from './odoo';

export var randomKeycloakRoleName = {
roleName : `${(Math.random() + 1).toString(36).substring(2)}`
Expand Down Expand Up @@ -82,6 +83,12 @@ export class Keycloak {
await this.page.getByRole('button', { name: 'Search' }).press('Enter');
}

async searchOdooRole() {
await expect(this.page.getByPlaceholder('Search role by name')).toBeVisible();
await this.page.getByPlaceholder('Search role by name').fill(`${randomOdooGroupName.groupName}`);
await this.page.getByRole('button', { name: 'Search' }).press('Enter');
}

async navigateToClientAttributes() {
await this.page.getByRole('link', { name: `${randomOpenMRSRoleName.roleName}` }).click();
await this.page.getByTestId('attributesTab').click();
Expand Down
76 changes: 72 additions & 4 deletions e2e/utils/functions/odoo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,30 @@ import { ODOO_URL } from '../configs/globalSetup';
import { Keycloak } from './keycloak';
import { delay, patientName } from './openmrs';

export var randomOdooGroupName = {
groupName : `${Array.from({ length: 8 }, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97)).join('')}`,
updatedGroupName : `${Array.from({ length: 8 }, () => String.fromCharCode(Math.floor(Math.random() * 26) + 97)).join('')}`
}

export class Odoo {
constructor(readonly page: Page) {}

async open() {
await this.page.goto(`${ODOO_URL}`);
if (`${process.env.TEST_PRO}` == 'true') {
await this.page.locator('div.o_login_auth div a').click();
await this.page.getByRole('link', { name: 'Login with Single Sign-On' }).click();
} else {
await this.page.locator('#login').fill(`${process.env.ODOO_USERNAME_ON_FOSS}`);
await this.page.locator('#password').fill(`${process.env.ODOO_PASSWORD_ON_FOSS}`);
await this.page.locator('button[type="submit"]').click();
await this.enterLoginCredentials();
}
await expect(this.page).toHaveURL(/.*web/);
}

async enterLoginCredentials() {
await this.page.locator('#login').fill(`${process.env.ODOO_USERNAME_ON_FOSS}`);
await this.page.locator('#password').fill(`${process.env.ODOO_PASSWORD_ON_FOSS}`);
await this.page.locator('button[type="submit"]').click();
}

async searchCustomer() {
await expect(this.page.locator('.o_searchview_input')).toBeVisible();
await this.page.locator('.o_searchview_input').fill(`${patientName.firstName + ' ' + patientName.givenName}`);
Expand Down Expand Up @@ -55,6 +64,65 @@ export class Odoo {
await expect(this.page.locator('td.o_data_cell:nth-child(11)')).toHaveText('$ 16.00');
}

async activateDeveloperMode() {
await this.navigateToSettings();
await expect(this.page.locator('#devel_tool a:nth-child(1)')).toBeVisible();
await this.page.locator('#devel_tool a:nth-child(1)').click();
}

async navigateToGroups() {
await this.navigateToSettings();
await expect(this.page.locator('ul.o_menu_sections>:nth-child(2)>a')).toBeVisible();
await this.page.locator('ul.o_menu_sections>:nth-child(2)>a').click();
await expect(this.page.getByRole('menuitem', { name: /groups/i })).toBeVisible();
await this.page.getByRole('menuitem', { name: /groups/i }).click();
}

async navigateToSettings() {
await this.page.locator("//a[contains(@class, 'full')]").click();
await expect(this.page.getByRole('menuitem', { name: /settings/i })).toBeVisible();
await this.page.getByRole('menuitem', { name: /settings/i }).click();
}

async createGroup() {
await this.page.getByRole('button', { name: /create/i }).click();
await this.page.getByLabel(/application/i).click();
await expect(this.page.getByText(/accounting/i)).toBeVisible();
await this.page.getByText(/accounting/i).click();
await this.page.getByLabel(/name/i).fill(`${randomOdooGroupName.groupName}`);
await this.page.getByRole('button', { name: /save/i }).click();
await delay(240000);
}

async searchGroup() {
await this.page.getByLabel(/remove/i).click();
await expect(this.page.locator('div>div>input')).toBeVisible();
await this.page.locator('div>div>input').type(`${randomOdooGroupName.groupName}`);
await this.page.locator('div>div>input').press('Enter');
await this.page.getByRole('cell', { name: `${randomOdooGroupName.groupName}` }).click();
}

async updateGroup() {
await expect(this.page.getByRole('button', { name: /edit/i })).toBeVisible();
await this.page.getByRole('button', { name: /edit/i }).click();
await this.page.getByLabel(/name/i).clear();
await this.page.getByLabel(/name/i).fill(`${randomOdooGroupName.updatedGroupName}`);
await this.page.getByRole('button', { name: /save/i }).click();
await delay(150000);
}

async deleteGroup() {
await expect(this.page.getByRole('button', { name: /action/i })).toBeVisible();
await this.page.getByRole('button', { name: /action/i }).click();
await expect(this.page.getByRole('menuitemcheckbox', { name: /delete/i })).toBeVisible();
await this.page.getByRole('menuitemcheckbox', { name: /delete/i }).click();
await expect(this.page.getByRole('button', { name: /ok/i })).toBeVisible();
await this.page.getByRole('button', { name: /ok/i }).click();
await delay(2000);
await expect(this.page.getByText(`${randomOdooGroupName.groupName}` )).not.toBeVisible();
await delay(150000);
}

async logout() {
await this.page.goto(`${ODOO_URL}`);
await expect(this.page.locator('.o_user_menu>a')).toBeVisible();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"!playwright-report/"
],
"scripts": {
"ozone-pro": "npx playwright test",
"ozone-pro": "npx playwright test keycloak-odoo",
"ozone-foss": "npx playwright test odoo-openmrs erpnext-openmrs openmrs-senaite",
"openmrs-distro-his": "npx playwright test odoo-openmrs openmrs-senaite"
},
Expand Down
6 changes: 4 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dotenv.config();

const config: PlaywrightTestConfig = {
testDir: './e2e/tests',
timeout: 3 * 60 * 1000,
timeout: 4 * 60 * 1000,
expect: {
timeout: 40 * 1000,
},
Expand All @@ -24,7 +24,9 @@ const config: PlaywrightTestConfig = {
name: 'chromium',
use: {
...devices['Desktop Chromium'],
viewport: { width: 1920, height: 1080 }
viewport: { width: 1920, height: 1080 },
video: 'retain-on-failure',
screenshot: 'only-on-failure'
},

},
Expand Down

0 comments on commit 0096de9

Please sign in to comment.