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

e2e-test: add test cov for 'open changes' in editor action bar #5836

Merged
merged 3 commits into from
Dec 19, 2024
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
136 changes: 87 additions & 49 deletions test/e2e/areas/action-bar/editor-action-bar.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
*--------------------------------------------------------------------------------------------*/

import { test, expect, tags } from '../_test.setup';
import { Application } from '../../../automation';
import { Page } from '@playwright/test';
import path = require('path');


test.use({
suiteId: __filename
});

test.describe('Editor Action Bar', {
tag: [tags.WEB, tags.ACTION_BAR, tags.EDITOR]
tag: [tags.WEB, tags.EDITOR_ACTION_BAR, tags.EDITOR]
}, () => {

test.beforeAll(async function ({ userSettings }) {
await userSettings.set([['editor.actionBar.enabled', 'true']], false);
});
Expand All @@ -25,90 +29,61 @@ test.describe('Editor Action Bar', {
tag: [tags.R_MARKDOWN]
}, async function ({ app, page }) {
await openFile(app, 'workspaces/basic-rmd-file/basicRmd.rmd');

await test.step('verify "preview" button renders html', async () => {
await page.getByLabel('Preview', { exact: true }).click();
const viewerFrame = app.workbench.positronViewer.getViewerFrame().frameLocator('iframe');
await expect(viewerFrame.getByRole('heading', { name: 'Getting startedAnchor' })).toBeVisible({ timeout: 30000 });
});

await verifyPreviewRendersHtml(app, 'Getting startedAnchor');
await verifySplitEditor(page, 'basicRmd.rmd');
await verifyOpenInNewWindow(page, 'This post examines the features');
});


test('Quarto Document [C1080700]', {
tag: [tags.QUARTO]
}, async function ({ app, page }) {
await openFile(app, 'workspaces/quarto_basic/quarto_basic.qmd');

await test.step('verify "preview" button renders html', async () => {
await page.getByLabel('Preview', { exact: true }).click();
const viewerFrame = app.workbench.positronViewer.getViewerFrame().frameLocator('iframe');
await expect(viewerFrame.locator('h1')).toHaveText('Diamond sizes', { timeout: 30000 });
});

await verifyPreviewRendersHtml(app, 'Diamond sizes');
await verifyOpenChanges(page);
await verifySplitEditor(page, 'quarto_basic.qmd');
await verifyOpenInNewWindow(page, 'Diamond sizes');
});

test('HTML Document [C1080701]', { tag: [tags.HTML] }, async function ({ app, page }) {
await openFile(app, 'workspaces/dash-py-example/data/OilandGasMetadata.html');

await test.step('verify "open in viewer" button renders html', async () => {
await page.getByLabel('Open in Viewer').nth(1).click();
const viewerFrame = page.locator('iframe.webview').contentFrame().locator('#active-frame').contentFrame();
const cellLocator = app.web
? viewerFrame.frameLocator('iframe').getByRole('cell', { name: 'Oil, Gas, and Other Regulated' })
: viewerFrame.getByRole('cell', { name: 'Oil, Gas, and Other Regulated' });

await expect(cellLocator).toBeVisible({ timeout: 30000 });
});

await verifyOpenViewerRendersHtml(app);
await verifySplitEditor(page, 'OilandGasMetadata.html');
await verifyOpenInNewWindow(page, '<title> Oil &amp; Gas Wells - Metadata</title>');

});

test('Jupyter Notebook [C1080702]', {
tag: [tags.NOTEBOOK],
annotation: [{ type: 'info', description: 'electron test unable to interact with dropdown native menu' }],
}, async function ({ app, page }) {
await test.step('open jupyter notebook', async () => {
await app.workbench.positronQuickaccess.openDataFile(
path.join(app.workspacePathOrFolder, 'workspaces', 'large_r_notebook', 'spotify.ipynb')
);
});
await openNotebook(app, 'workspaces/large_r_notebook/spotify.ipynb');
await verifySplitEditor(page, 'spotify.ipynb');

if (app.web) {
await test.step('verify "customize notebook: toggle line numbers" adjusts settings (web only)', async () => {
await verifyLineNumbersVisibility(page, false);
await clickCustomizeNotebookMenuItem(page, 'Toggle Notebook Line Numbers');
await verifyLineNumbersVisibility(page, true);
});

await test.step('verify "customize notebook: toggle breadcrumbs" adjusts settings (web only)', async () => {
const breadcrumbs = page.locator('.monaco-breadcrumbs');

await expect(breadcrumbs).toBeVisible();
await clickCustomizeNotebookMenuItem(page, 'Toggle Breadcrumbs');
await expect(breadcrumbs).not.toBeVisible();
});
await verifyToggleLineNumbers(page);
await verifyToggleBreadcrumb(page);
}

await verifySplitEditor(page, 'spotify.ipynb');
});
});


// Helper functions
async function openFile(app, filePath: string) {
const fileName = path.basename(filePath);
await test.step(`open file: ${fileName}`, async () => {
await app.workbench.positronQuickaccess.openFile(path.join(app.workspacePathOrFolder, filePath));
});
}

async function openNotebook(app: Application, filePath: string) {
await test.step('open jupyter notebook', async () => {
await app.workbench.positronQuickaccess.openDataFile(
path.join(app.workspacePathOrFolder, filePath)
);
});
}

async function verifySplitEditor(page, tabName: string) {
await test.step(`verify "split editor" button opens another tab`, async () => {
await test.step(`verify "split editor" opens another tab`, async () => {
// Split editor right
await page.getByLabel('Split Editor Right', { exact: true }).click();
await expect(page.getByRole('tab', { name: tabName })).toHaveCount(2);
Expand Down Expand Up @@ -152,3 +127,66 @@ async function verifyLineNumbersVisibility(page, isVisible: boolean) {
isVisible ? await lineNumbers.toBeVisible() : await lineNumbers.not.toBeVisible();
}
}

async function verifyOpenChanges(page: Page) {
await test.step('verify "open changes" shows diff', async () => {


// make change & save
await page.getByText('date', { exact: true }).click();
await page.keyboard.press('X');
await bindPlatformHotkey(page, 'S');

// click open changes & verify
await page.getByLabel('Open Changes').nth(1).click();
await expect(page.getByLabel('Revert Block')).toBeVisible();
await expect(page.getByLabel('Stage Block')).toBeVisible();
await page.getByRole('tab', { name: 'quarto_basic.qmd (Working' }).getByLabel('Close').click();

// undo changes & save
await bindPlatformHotkey(page, 'Z');
await bindPlatformHotkey(page, 'S');
});
}

async function bindPlatformHotkey(page: Page, key: string) {
await page.keyboard.press(process.platform === 'darwin' ? `Meta+${key}` : `Control+${key}`);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

seems like we may need a new place to start collecting things like this. i.e. general purpose helper functions. not necessary for this PR but maybe keep in mind that we might want a positronCode.ts or something

Copy link
Contributor

Choose a reason for hiding this comment

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

(and that might be a good step towards getting unhooked from the MS dependencies)
Would be great if everything didn't depend on code.ts since code.ts is loaded with getElements, etc
argh

async function verifyOpenViewerRendersHtml(app: Application) {
await test.step('verify "open in viewer" renders html', async () => {
await app.code.driver.page.getByLabel('Open in Viewer').nth(1).click();
const viewerFrame = app.code.driver.page.locator('iframe.webview').contentFrame().locator('#active-frame').contentFrame();
const cellLocator = app.web
Copy link
Contributor

@testlabauto testlabauto Dec 19, 2024

Choose a reason for hiding this comment

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

should some of this be in positronViewer? It seems like there is a bit of duplication

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe? I'm on the fence. I usually don't put verifications in the POM, but certainly interacting with the buttons could be in there. I can do a followup PR to move some of this into the PositronViewer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Or would it be PositronEditor? Maybe both, I guess I'll find out...

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, agreed about verifications in the POM. we definitely have some but not my favorite. was thinking more about locators that might be reusable

? viewerFrame.frameLocator('iframe').getByRole('cell', { name: 'Oil, Gas, and Other Regulated' })
: viewerFrame.getByRole('cell', { name: 'Oil, Gas, and Other Regulated' });

await expect(cellLocator).toBeVisible({ timeout: 30000 });
});
}

async function verifyPreviewRendersHtml(app: Application, heading: string) {
await test.step('verify "preview" renders html', async () => {
await app.code.driver.page.getByLabel('Preview', { exact: true }).click();
const viewerFrame = app.workbench.positronViewer.getViewerFrame().frameLocator('iframe');
await expect(viewerFrame.getByRole('heading', { name: heading })).toBeVisible({ timeout: 30000 });
});
}

async function verifyToggleLineNumbers(page: Page) {
await test.step('verify "customize notebook > toggle line numbers" (web only)', async () => {
await verifyLineNumbersVisibility(page, false);
await clickCustomizeNotebookMenuItem(page, 'Toggle Notebook Line Numbers');
await verifyLineNumbersVisibility(page, true);
});
}

async function verifyToggleBreadcrumb(page: Page) {
await test.step('verify "customize notebook > toggle breadcrumbs" (web only)', async () => {
const breadcrumbs = page.locator('.monaco-breadcrumbs');

await expect(breadcrumbs).toBeVisible();
await clickCustomizeNotebookMenuItem(page, 'Toggle Breadcrumbs');
await expect(breadcrumbs).not.toBeVisible();
});
}
2 changes: 1 addition & 1 deletion test/e2e/helpers/test-tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* which are not currently configured to run in PR workflows.
*/
export enum TestTags {
ACTION_BAR = '@action-bar',
EDITOR_ACTION_BAR = '@editor-action-bar',
APPS = '@apps',
CONNECTIONS = '@connections',
CONSOLE = '@console',
Expand Down
Loading