Skip to content

Commit

Permalink
Add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
brichet committed Apr 12, 2024
1 parent 1e4e417 commit e60b7c7
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ jobs:
run: |
set -eux
python -m pip install "jupyterlab>=4.0.0,<5" jupyterlab_${{ matrix.extension }}_chat*.whl
- name: Install dependencies
working-directory: packages/jupyterlab-${{ matrix.extension }}-chat/ui-tests
env:
Expand All @@ -125,6 +126,7 @@ jobs:
working-directory: packages/jupyterlab-${{ matrix.extension }}-chat/ui-tests
run: |
jlpm playwright test
- name: Upload Playwright Test report
if: always()
uses: actions/upload-artifact@v3
Expand Down
6 changes: 5 additions & 1 deletion packages/jupyterlab-collaborative-chat/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,11 @@ const chatCommands: JupyterFrontEndPlugin<void> = {
/**
* Initialize the chat model with the share model
*/
const chat = new CollaborativeChatModel({ awareness, sharedModel, widgetConfig });
const chat = new CollaborativeChatModel({
awareness,
sharedModel,
widgetConfig
});

/**
* Add a chat widget to the side panel.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const fillModal = async (
page: IJupyterLabPageFixture,
text = '',
button: 'Ok' | 'Cancel' = 'Ok'
) => {
): Promise<void> => {
const dialog = page.getByRole('dialog');
await dialog.getByRole('textbox').pressSequentially(text);
await dialog.getByRole('button').filter({ hasText: button }).click();
Expand Down Expand Up @@ -48,6 +48,17 @@ const openSettings = async (
return (await page.activity.getPanelLocator('Settings')) as Locator;
};

const openPanel = async (page: IJupyterLabPageFixture): Promise<Locator> => {
const panel = page.locator('.jp-SidePanel.jp-collab-chat-sidepanel');

if (!(await panel?.isVisible())) {
const chatIcon = page.getByTitle('Jupyter Chat');
await chatIcon.click();
await expect(panel).toBeVisible();
}
return panel.first();
};

test.describe('#commandPalette', () => {
const name = 'my-chat';

Expand Down Expand Up @@ -338,3 +349,142 @@ test.describe('#settings', () => {
).toBe(msg + '\n');
});
});

test.describe('#chatPanel', () => {
test.describe('#initiailization', () => {
test('should contain the chat panel icon', async ({ page }) => {
const chatIcon = page.getByTitle('Jupyter Chat');
expect(chatIcon).toHaveCount(1);
expect(await chatIcon.screenshot()).toMatchSnapshot(
'chat_icon.png'
);
});

test('chat panel should contain a toolbar', async ({ page }) => {
const panel = await openPanel(page);
const toolbar = panel.locator('.jp-SidePanel-toolbar');
await expect(toolbar).toHaveCount(1);

const items = toolbar.locator('.jp-Toolbar-item');
await expect(items).toHaveCount(2);
await expect(items.first()).toHaveClass(/.jp-collab-chat-add/);
await expect(items.last()).toHaveClass(/.jp-collab-chat-open/);
});

test('chat panel should not contain a chat at init', async ({ page }) => {
const panel = await openPanel(page);
const content = panel.locator('.jp-SidePanel-content');
await expect(content).toBeEmpty();
});
})

test.describe('#chatCreation', () => {
const name = 'my-chat';
let panel: Locator;
let dialog: Locator;

test.beforeEach(async ({ page }) => {
panel = await openPanel(page);
const addButton = panel.locator(
'.jp-SidePanel-toolbar .jp-Toolbar-item.jp-collab-chat-add'
);
await addButton.click();

dialog = page.locator('.jp-Dialog');
await dialog.waitFor();
});

test.afterEach(async ({ page })=> {
for (let filename of ['untitled.chat', `${name}.chat`]) {
if (await page.filebrowser.contents.fileExists(filename)) {
await page.filebrowser.contents.deleteFile(filename);
}
}
});

test('should create a chat', async ({ page }) => {
await dialog.locator('input[type="text"]').pressSequentially(name);
await dialog.getByRole('button').getByText('Ok').click();
await page.waitForCondition(
async () => await page.filebrowser.contents.fileExists(`${name}.chat`)
);

const chatTitle = panel.locator('.jp-SidePanel-content .jp-AccordionPanel-title');
await expect(chatTitle).toHaveCount(1);
await expect(chatTitle.locator('.lm-AccordionPanel-titleLabel')).toHaveText(
name
);
});

test('should create an untitled file if no name is provided', async ({ page }) => {
await dialog.getByRole('button').getByText('Ok').click();
await page.waitForCondition(
async () => await page.filebrowser.contents.fileExists('untitled.chat')
);

const chatTitle = panel.locator('.jp-SidePanel-content .jp-AccordionPanel-title');
await expect(chatTitle).toHaveCount(1);
await expect(chatTitle.locator('.lm-AccordionPanel-titleLabel')).toHaveText(
'untitled'
);
});

test('should not create a chat if dialog is cancelled', async ({ page }) => {
await dialog.getByRole('button').getByText('Cancel').click();

const content = panel.locator('.jp-SidePanel-content');
await expect(content).toBeEmpty();
});
})

test.describe('#openingClosing', () => {
const name = 'my-chat';
let panel: Locator;
let select: Locator;

test.beforeEach(async ({ page }) => {
await page.filebrowser.contents.uploadContent('{}', 'text', `${name}.chat`);
});

test.afterEach(async ({ page }) => {
await page.filebrowser.contents.deleteFile( `${name}.chat`);
});

test('should list existing chat', async ({ page }) => {
// reload to update the chat list
// FIX: add listener on file creation
await page.reload();
panel = await openPanel(page);
select = panel.locator(
'.jp-SidePanel-toolbar .jp-Toolbar-item.jp-collab-chat-open select'
);

for (let i=0; i< await select.locator('option').count(); i++) {
console.log(await select.locator('option').nth(i).textContent());
}
await expect(select.locator('option')).toHaveCount(2);
await expect(select.locator('option').last()).toHaveText(name);
});

test('should open an existing chat and close it', async ({ page }) => {
// reload to update the chat list
// FIX: add listener on file creation
await page.reload();
panel = await openPanel(page);
select = panel.locator(
'.jp-SidePanel-toolbar .jp-Toolbar-item.jp-collab-chat-open select'
);

await select.selectOption(name);

const chatTitle = panel.locator('.jp-SidePanel-content .jp-AccordionPanel-title');
await expect(chatTitle).toHaveCount(1);
await expect(chatTitle.locator('.lm-AccordionPanel-titleLabel')).toHaveText(
name
);

await chatTitle.getByRole('button').click();
await expect(chatTitle).toHaveCount(0);
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e60b7c7

Please sign in to comment.