Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

task/WMAQA-45 Shared Workspace Tests #23

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
13 changes: 11 additions & 2 deletions playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = defineConfig({
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
retries: process.env.CI ? 2 : 1,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
Expand Down Expand Up @@ -49,7 +49,8 @@ module.exports = defineConfig({
portal: process.env.PORTAL,
environment: process.env.ENVIRONMENT,
baseURL: `https://${NGINX_SERVER_NAME}`
}
},
teardown: 'teardown'
},
{
name: 'default',
Expand Down Expand Up @@ -81,6 +82,14 @@ module.exports = defineConfig({
environment: process.env.ENVIRONMENT,
},
dependencies: ['setup'],
},
{
name: 'teardown',
testMatch: 'teardown/*.teardown.js',
use: {
storageState: 'playwright/.auth/user.json',
baseURL: `https://${NGINX_SERVER_NAME}`
}
}

// {
Expand Down
85 changes: 85 additions & 0 deletions tests/data-files/data-files-shared-workspace.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { expect } from '@playwright/test';
import { test } from '../../fixtures/baseFixture';
import { PORTAL_DATAFILES_STORAGE_SYSTEMS } from '../../settings/custom_portal_settings.json';

const portalStorageSystems = PORTAL_DATAFILES_STORAGE_SYSTEMS

test.describe.configure({ mode: 'serial' })

test.describe('Shared Workspaces tests', () => {

// Skip the tests if portal does not have Shared Workspaces
test.skip(!portalStorageSystems.some(system => (system.scheme === 'projects')))

test.beforeEach(async ({ page, baseURL }) => {
await page.goto(baseURL);
await page.locator('#navbarDropdown').click();
await page.getByRole('link', { name: 'Dashboard' }).click();
await page.getByRole('link', { name: 'Data Files' }).click();
await page.getByRole('main').getByRole('link', { name: 'Shared Workspaces' }).click();
})

test('Add Shared Workspace', async ({ page }) => {
test.setTimeout(100000)
await page.getByRole('button', { name: '+ Add' }).click();
await page.getByRole('menuitem', { name: 'Shared Workspace' }).click();

await expect(page.locator('.modal-dialog')).toBeVisible();
await page.getByRole('textbox').click();
await page.getByRole('textbox').fill('Test Shared Workspace');

await expect(page.locator('.project-members__cell').nth(0)).toContainText('WMA Test User')

await page.getByRole('button', { name: 'Add Workspace' }).click();

await expect(page.locator('.modal-dialog')).not.toBeVisible({timeout: 20000});

await expect(page.locator('.listing-placeholder')).toBeVisible();

await expect(page.getByRole('heading', {level: 3})).toHaveText('Test Shared Workspace')

await page.getByRole('main').getByRole('link', { name: 'Shared Workspaces' }).click();

const table = page.getByRole('table').and(page.locator('.projects-listing'))
const rows = await table.locator('tbody').locator('tr').all()

expect(rows.length).toBeGreaterThanOrEqual(1);

})

test('Shared Workspace Search', async ({ page }) => {
const input = page.getByRole('form', { name: 'Workspace Search' }).locator('input')
const searchButton = page.getByRole('form', { name: 'Workspace Search' }).getByRole('button', { name: 'Search', exact: true })
const table = page.getByRole('table').and(page.locator('.projects-listing'))

await input.fill('Test Shared Workspace')
await searchButton.click();
const rows = await table.locator('tbody').locator('tr').all()
expect(rows.length).toBe(1);

await input.fill('random string')
await searchButton.click();
await expect(table).toContainText("No Shared Workspaces match your search term.")
})

test('Edit Shared Workspace Name and Description', async ({ page }) => {
await page.getByRole('link', { name: 'Test Shared Workspace' }).click();
await page.getByRole('button', { name: 'Edit Descriptions' }).click();

await expect(page.locator('.modal-dialog')).toBeVisible();

await page.getByLabel('title').click();
await page.getByLabel('title').fill('');
await page.getByLabel('title').fill('Test Shared Workspace Rename');

await page.getByLabel('description').click();
await page.getByLabel('description').fill('Workspace description');

await page.getByRole('button', { name: 'Update Changes' }).click();

await expect(page.locator('.modal-dialog')).not.toBeVisible();
shayanaijaz marked this conversation as resolved.
Show resolved Hide resolved

await expect(page.getByRole('heading', {level: 3})).toHaveText('Test Shared Workspace Rename')
await expect(page.getByText('Workspace description')).toBeVisible()
})
})
97 changes: 97 additions & 0 deletions tests/teardown/data-files-shared-workspaces.teardown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { expect } from '@playwright/test';
import { test } from '../../fixtures/baseFixture';
import { PORTAL_PROJECTS_SYSTEM_PREFIX } from '../../settings/custom_portal_settings.json'

test('Cleanup shared workspaces', async ({ page, baseURL }) => {

const tenant = 'https://portals.tapis.io';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is ok for now, but we're going to need to parameterize this if we want to test portals on different tenants.

const projectPrefix = PORTAL_PROJECTS_SYSTEM_PREFIX;

let systems = []

try {
const accessToken = await getAccessToken(page, baseURL)

systems = await getSystems(page, tenant, projectPrefix, accessToken)

console.log(`Teardown: Found ${systems.length} shared workspaces to delete ${systems}`)

for (const system of systems) {
await deleteSystem(page, system.id, tenant, accessToken)
console.info(`Teardown: Shared workspace with id ${system.id} deleted`)
}
} catch (e) {
console.error(`An error occured when deleting shared workspaces: ${e.message}`)
}

// Ensure there are no shared workspaces left over
await page.goto(baseURL);
await page.locator('#navbarDropdown').click();
await page.getByRole('link', { name: 'Dashboard' }).click();
await page.getByRole('link', { name: 'Data Files' }).click();
await page.getByRole('main').getByRole('link', { name: 'Shared Workspaces' }).click();

const table = page.getByRole('table').and(page.locator('.projects-listing'))
const rows = await table.locator('tbody').locator('tr').all()

if (rows.length > 0) {
const links = await page.locator('.data-files-nav-link').all();

for (const system of systems) {
for (const link of links) {
const href = await link.getAttribute('href');
expect(href).not.toContain(system.id);
}
}
}
})

async function getAccessToken(page, baseURL) {
const url = `${baseURL}/api/auth/tapis`;

const cookies = await page.context().cookies()

const headers = {
'Cookie': cookies.map(cookie => `${cookie.name}=${cookie.value}`).join('; ')
};

const response = await page.request.get(url, {headers: headers});
const jsonResponse = await response.json();
return jsonResponse.token;
}


async function getSystems(page, tenant, projectPrefix, accessToken) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to delete all the shared systems, or just the one we created in these tests? Is there an easy or free way to get that system id at system creation? I'll take a look to try and save you a headache.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it looks like it's available in the Shared Workspaces view and in the URL.


console.log('Getting systems with prefix: ', projectPrefix)
// get systems that match the prefix of the current portal
const url = `${tenant}/v3/systems?search=(id.like.${projectPrefix}*)`;

return await page.evaluate(async ({url, accessToken}) => {
const response = await fetch(url, {
headers: {
"X-Tapis-Token": accessToken
}
});

const jsonResponse = await response.json();
return jsonResponse.result;

}, {url, accessToken})
}

async function deleteSystem(page, systemId, tenant, accessToken) {

const url = `${tenant}/v3/systems/${systemId}/delete`;

return await page.evaluate(async ({url, accessToken}) => {
const response = await fetch(url, {
method: 'POST',
headers: {
"X-Tapis-Token": accessToken
}
});

return await response.json();
}, {url, accessToken})
}
3 changes: 2 additions & 1 deletion utils/pythonHelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"PORTAL_DATAFILES_STORAGE_SYSTEMS": custom_portal_settings._PORTAL_DATAFILES_STORAGE_SYSTEMS or [],
"SYSTEM_MONITOR_DISPLAY_LIST": custom_portal_settings._SYSTEM_MONITOR_DISPLAY_LIST or [],
"NGINX_SERVER_NAME": os.getenv('NGINX_SERVER_NAME'),
"WORKBENCH_SETTINGS":custom_portal_settings._WORKBENCH_SETTINGS or []
"WORKBENCH_SETTINGS":custom_portal_settings._WORKBENCH_SETTINGS or [],
"PORTAL_PROJECTS_SYSTEM_PREFIX": custom_portal_settings._PORTAL_PROJECTS_SYSTEM_PREFIX or ''
fnets marked this conversation as resolved.
Show resolved Hide resolved
}

with open(output_path, 'w') as json_file:
Expand Down