Skip to content
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
12 changes: 10 additions & 2 deletions .github/workflows/copilot-test-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,15 @@ jobs:
env:
AzureOpenAI__ApiKey: ${{ secrets.AZUREOPENAI__APIKEY }}
AzureOpenAI__Endpoint: ${{ secrets.AZUREOPENAI__ENDPOINT }}
TenantId: ${{ secrets.COPILOT_CHAT_TEST_APP_AAD_TENANT_ID }}
WebApi_ClientId: ${{ secrets.COPILOT_CHAT_TEST_APP_AAD_WEBAPI_CLIENT_ID }}
run: |
dotnet dev-certs https
dotnet user-secrets set "AIService:Key" "$AzureOpenAI__ApiKey"
dotnet user-secrets set "AIService:Endpoint" "$AzureOpenAI__Endpoint"
dotnet user-secrets set "Authentication:Type" "AzureAd"
dotnet user-secrets set "Authentication:AzureAd:TenantId" "$TenantId"
dotnet user-secrets set "Authentication:AzureAd:ClientId" "$WebApi_ClientId"

- name: Start service in background
working-directory: webapi
Expand All @@ -63,8 +68,11 @@ jobs:
- name: Run Playwright tests
env:
REACT_APP_BACKEND_URI: https://localhost:40443/
REACT_APP_AAD_CLIENT_ID: ${{ secrets.COPILOT_CHAT_REACT_APP_AAD_CLIENT_ID }}
REACT_APP_AAD_AUTHORITY: https://login.microsoftonline.com/common

REACT_APP_AUTH_TYPE: AzureAd
REACT_APP_AAD_AUTHORITY: https://login.microsoftonline.com/${{ secrets.COPILOT_CHAT_TEST_APP_AAD_TENANT_ID }}
REACT_APP_AAD_CLIENT_ID: ${{ secrets.COPILOT_CHAT_TEST_APP_AAD_CLIENT_ID }}
REACT_APP_AAD_API_SCOPE: api://${{ secrets.COPILOT_CHAT_TEST_APP_AAD_WEBAPI_CLIENT_ID }}/access_as_user

REACT_APP_TEST_USER_ACCOUNT1: ${{ secrets.COPILOT_CHAT_TEST_USER_ACCOUNT1 }}
REACT_APP_TEST_USER_ACCOUNT1_INITIALS: ${{ secrets.COPILOT_CHAT_TEST_USER_ACCOUNT1_INITIALS }}
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const Chat = ({
<Subtitle1 as="h1">Chat Copilot</Subtitle1>
{appState > AppState.SettingUserInfo && (
<div className={classes.cornerItems}>
<div data-testid="logOutMenuList" className={classes.cornerItems}>
<div className={classes.cornerItems}>
<PluginGallery />
<UserSettingsMenu
setLoadingState={() => {
Expand Down
1 change: 1 addition & 0 deletions webapp/src/components/chat/chat-list/ListItemActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const ListItemActions: React.FC<IListItemActionsProps> = ({ chatId, onEdi
appearance="transparent"
aria-label="Edit chat name"
onClick={onEditTitleClick}
data-testid="editChatTitleButtonSimplified"
/>
</Tooltip>
<Tooltip content={'Download chat session'} relationship="label">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ export const InvitationCreateDialog: React.FC<InvitationCreateDialogProps> = ({
<DialogTitle>Invite others to your Bot</DialogTitle>
<DialogContent className={classes.content}>
<Label>Please provide the following Chat ID to your friends so they can join the chat.</Label>
<Label data-testid="chatIDLabel" weight="semibold">
<Label data-testid="invitationDialogChatIDLabel" weight="semibold">
{chatId}
</Label>
</DialogContent>
<DialogActions>
<Button data-testid="chatIDCloseButton" appearance="secondary" onClick={onCancel}>
<Button data-testid="invitationDialogCloseButton" appearance="secondary" onClick={onCancel}>
Close
</Button>
<Button
data-testid="chatIDCopyButton"
data-testid="invitationDialogChatIDCopyButton"
appearance="primary"
onClick={copyId}
icon={isIdCopied ? <Checkmark20Filled /> : null}
Expand Down
3 changes: 2 additions & 1 deletion webapp/src/components/header/UserSettingsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const UserSettingsMenu: FC<IUserSettingsProps> = ({ setLoadingState }) =>
? { status: 'available' }
: undefined
}
data-testid="userSettingsButton"
/>
}
</MenuTrigger>
Expand Down Expand Up @@ -101,7 +102,7 @@ export const UserSettingsMenu: FC<IUserSettingsProps> = ({ setLoadingState }) =>
</Menu>
) : (
<Button
data-testid="settingsButton"
data-testid="settingsButtonWithoutAuth"
style={{ color: 'white' }}
appearance="transparent"
icon={<Settings24Regular color="white" />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const SettingSection: React.FC<ISettingsSectionProps> = ({ setting, conte
onChange={() => {
onFeatureChange(key);
}}
data-testid={feature.label}
/>
<Text
className={classes.featureDescription}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export const SettingsDialog: React.FC<ISettingsDialogProps> = ({ open, closeDial
</AccordionItem>
<Divider />
<AccordionItem value="advanced">
<AccordionHeader expandIconPosition="end">
<AccordionHeader expandIconPosition="end" data-testid="advancedSettingsFoldup">
<h3>Advanced</h3>
</AccordionHeader>
<AccordionPanel>
Expand Down Expand Up @@ -120,7 +120,9 @@ export const SettingsDialog: React.FC<ISettingsDialogProps> = ({ open, closeDial
</a>
</Label>
<DialogTrigger disableButtonEnhancement>
<Button appearance="secondary">Close</Button>
<Button appearance="secondary" data-testid="userSettingsCloseButton">
Close
</Button>
</DialogTrigger>
</DialogActions>
</DialogSurface>
Expand Down
1 change: 1 addition & 0 deletions webapp/src/components/views/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const Login: React.FC = () => {
onClick={() => {
instance.loginRedirect().catch(() => {});
}}
data-testid="signinButton"
>
<Image src={signInLogo} />
</Button>
Expand Down
2 changes: 1 addition & 1 deletion webapp/tests/chat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ test.describe('Copilot Chat App Test Suite', () => {
await plannertests.klarnaTest(page);
});

test('Jira', async ({ page }) => {
test.skip('Jira', async ({ page }) => {
test.setTimeout(util.TestTimeout);
await plannertests.jiraTest(page);
});
Expand Down
30 changes: 15 additions & 15 deletions webapp/tests/testsBasic.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { expect } from '@playwright/test';
import * as util from './utils'
import * as util from './utils';

/*
Summary: Checks if the server is running and healthy
*/
export async function serverHealth( page ) {
export async function serverHealth(page) {
// Make sure the server is running.
await page.goto('https://localhost:40443/healthz');
await expect(page.getByText('Healthy')).toBeDefined();
Expand All @@ -19,13 +19,13 @@ Summary: Tests for the following behaviour from the WebApp:
- Chat History has the correct number of messages and that the last message is from Copilot
- SK core skill testing for jokes and fun facts
*/
export async function basicBotResponses( page ) {
export async function basicBotResponses(page) {
await util.loginAndCreateNewChat(page);
const joke = "Can you tell me a funny joke about penguins?";

const joke = 'Can you tell me a funny joke about penguins?';
await util.sendChatMessageAndWaitForResponse(page, joke);

const funfact = "Tell me a fun fact about the cosmos!";
const funfact = 'Tell me a fun fact about the cosmos!';
await util.sendChatMessageAndWaitForResponse(page, funfact);

// Expect the chat history to contain 7 messages (both user messages and bot responses).
Expand All @@ -43,8 +43,8 @@ Summary: Tests if the title for the current chat can be changed
*/
export async function chatTitleChange(page) {
await util.loginAndCreateNewChat(page);
await page.getByTestId('editChatTitleButton').click();

await page.getByTestId('editChatTitleButtonSimplified').click();
await page.locator('input[type="text"]').fill('Copilot Unit Tests');
await page.locator('input[type="text"]').press('Enter');

Expand All @@ -54,17 +54,17 @@ export async function chatTitleChange(page) {
/*
Summary: Tests if a single document can be uploaded and then found in the 'Files' tab
*/
export async function documentUpload(page) {
export async function documentUpload(page) {
await util.loginAndCreateNewChat(page);

const testFilename = 'Lorem_ipsum.pdf';
const testFilepath = './../importdocument/sample-docs/' + testFilename;
await page.setInputFiles("input[type='file']", testFilepath)
await page.getByTestId('filesTab').click();// Go to the file page
const testFilepath = './../tools/importdocument/sample-docs/' + testFilename;
await page.setInputFiles("input[type='file']", testFilepath);

await page.getByTestId('documentsTab').click(); // Go to the documents tab
// Check if corresponding cell for the file exists after upload
await page.getByRole('cell', { name: testFilename }).locator('path');
await page.getByTestId('chatTab').click(); // Go back to the chat page

await util.postUnitTest(page);
}
}
33 changes: 25 additions & 8 deletions webapp/tests/testsMultiuser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@playwright/test';
import * as util from './utils'
import * as util from './utils';

/*
Summary: Tests the Multiuser feature of Copilot Chat. Specifically if a user can
Expand All @@ -14,32 +14,49 @@ export async function shareAndJoinChatSessionTest(page) {
await util.loginHelper(page, userAccount1, password1);
await util.createNewChat(page);

// Need to enable live chat session sharing to access the share button
await page.getByTestId('userSettingsButton').click();
await page.getByTestId('settingsMenuItem').click();
await page.getByTestId('advancedSettingsFoldup').click();
await page.getByTestId('Live Chat Session Sharing').click();
await page.getByTestId('userSettingsCloseButton').click();

await page.getByTestId('shareButton').click();
await page.getByTestId('inviteOthersMenuItem').click();

const labelByID = await page.getByTestId('chatIDLabel');
const labelByID = await page.getByTestId('invitationDialogChatIDLabel');
const chatId = await labelByID.textContent();
await page.getByTestId('chatIDCloseButton').click();
await page.getByTestId('invitationDialogCloseButton').click();

await page.getByTestId('logOutMenuList').click();
await page.getByTestId('userSettingsButton').click();
await page.getByTestId('logOutMenuButton').click();

const usernameToLowerCase = userAccount1.toLowerCase();
const locatorVal = ('[data-test-id="' + usernameToLowerCase + '"]') as string;
await page.locator(locatorVal).click();

// Login with the second user account
await util.loginHelperAnotherUser(page, userAccount2, password2);

// Need to enable live chat session sharing to access the join button
await page.getByTestId('userSettingsButton').click();
await page.getByTestId('settingsMenuItem').click();
await page.getByTestId('advancedSettingsFoldup').click();
await page.getByTestId('Simplified Chat Experience').click();
await page.getByTestId('Live Chat Session Sharing').click();
await page.getByTestId('userSettingsCloseButton').click();

await page.getByTestId('createNewConversationButton').click();
await page.getByTestId('joinABotMenuItem').click();
await page.getByTestId('enterChatIDLabel').fill(chatId as string);

await page.getByTestId('joinChatButton').click();

await page.waitForTimeout(util.ChatStateChangeWait);
await page.getByTestId('chatParticipantsView').click();

await page.getByTestId('chatParticipantsView').click();
const numPeople = await page.getByTestId('chatParticipantsView').textContent();
await expect(numPeople).toEqual("+2");
await expect(numPeople).toEqual('+2');

await util.postUnitTest(page);
}
}
13 changes: 10 additions & 3 deletions webapp/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const EvaluatePrompt =
export async function loginHelper(page, useraccount, password) {
await page.goto('/');
// Expect the page to contain a "Login" button.
await page.getByRole('button').click();
await page.getByTestId('signinButton').click();
// Clicking the login button should redirect to the login page.
await expect(page).toHaveURL(process.env.REACT_APP_AAD_AUTHORITY);
await expect(page).toHaveURL(new RegExp(`${process.env.REACT_APP_AAD_AUTHORITY}.*`));
// Login with the test user.
await page.getByPlaceholder('Email, phone, or Skype').click();
await page.getByPlaceholder('Email, phone, or Skype').fill(useraccount as string);
Expand All @@ -36,7 +36,7 @@ export async function loginHelperAnotherUser(page, useraccount, password) {
// Expect the page to contain a "Login" button.
await page.getByRole('button').click();
// Clicking the login button should redirect to the login page.
await expect(page).toHaveURL(process.env.REACT_APP_AAD_AUTHORITY);
await expect(page).toHaveURL(new RegExp(`${process.env.REACT_APP_AAD_AUTHORITY}.*`));
// Login with the another user account.
await page.getByRole('button', { name: 'Use another account' }).click();
await page.getByPlaceholder('Email, phone, or Skype').click();
Expand All @@ -48,6 +48,13 @@ export async function loginHelperAnotherUser(page, useraccount, password) {

// After login, the page should redirect back to the app.
await expect(page).toHaveTitle('Copilot Chat');

// Get the permission popup if they open
page.on('popup', async (popup) => {
await popup.waitForLoadState();
await popup.getByRole('button', { name: 'Next' }).click();
await popup.getByRole('button', { name: 'Accept' }).click();
});
}
export async function createNewChat(page) {
await page.getByTestId('createNewConversationButton').click();
Expand Down