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

Collaborative chat using jupyterlab_chat package #237

Closed
wants to merge 16 commits into from
Closed
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add tests on chat
brichet committed Mar 29, 2024
commit 91688a84151f26be01f590c2f3d1dd97771dce65
2 changes: 2 additions & 0 deletions ui-tests/jupyter_server_test_config.py
Original file line number Diff line number Diff line change
@@ -14,5 +14,7 @@
c: Any
configure_jupyter_server(c) # noqa

c.FileContentsManager.delete_to_trash = False

# Uncomment to set server log level to debug level
# c.ServerApp.log_level = "DEBUG"
145 changes: 145 additions & 0 deletions ui-tests/tests/chat.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/

import { expect, IJupyterLabPageFixture, test } from '@jupyterlab/galata';
import type { User } from '@jupyterlab/services';
import type { Locator } from '@playwright/test';

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('Initialization', () => {
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('Chat creation', () => {
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('should create a chat', async ({ page }) => {
await dialog.locator('input[type="text"]').type('chat-test');
await dialog.getByRole('button').getByText('Ok').click();
expect(await page.filebrowser.contents.fileExists('chat-test.chat')).toBeTruthy();

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

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

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('Opening/closing chat', () => {
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 page.pause();
await chatTitle.getByRole('button').click();
await page.pause();
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.