-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add basic smoke test for mattermost with sso (#65)
Fixes #75
- Loading branch information
1 parent
9228ee8
commit 074749c
Showing
10 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { test as setup, expect } from '@playwright/test'; | ||
import { authFile } from './playwright.config'; | ||
|
||
setup('authenticate', async ({ page, context, baseURL }) => { | ||
await page.goto('/login'); | ||
|
||
await page.getByRole("link", { name: "View in Browser" }).click(); | ||
await page.getByRole("link", { name: "Gitlab Icon GitLab" }).click(); | ||
await page.getByLabel("Username or email").fill("doug"); | ||
await page.getByLabel("Password").fill("unicorn123!@#"); | ||
await page.getByRole("button", { name: "Log In" }).click(); | ||
|
||
// ensure auth cookies were set | ||
const cookies = await context.cookies(); | ||
const keycloakCookie = cookies.find( | ||
(cookie) => cookie.name === "KEYCLOAK_SESSION", | ||
); | ||
|
||
expect(keycloakCookie).toBeDefined(); | ||
expect(keycloakCookie?.value).not.toBe(""); | ||
expect(keycloakCookie?.domain).toContain("sso."); | ||
|
||
await page.context().storageState({ path: authFile }); | ||
|
||
await page.waitForURL(url => | ||
url.pathname === '/' || | ||
url.pathname === '/preparing-workspace' || | ||
url.pathname === '/unicorns/channels/town-square' | ||
, { waitUntil: 'networkidle' }); | ||
|
||
// one-time workspace setup (when login redirects to "/preparing-workspace") | ||
if (page.url().endsWith('/preparing-workspace')) { | ||
const orgInput = page.getByPlaceholder("Organization name"); | ||
await orgInput.isVisible(); | ||
await orgInput.fill("Unicorns"); | ||
await page.getByTestId("continue").click(); | ||
await page.getByRole("button", { name: "Skip" }).click(); | ||
await page.getByRole("button", { name: "Finish setup" }).click(); | ||
}; | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { test, expect, request, APIRequestContext, Page } from "@playwright/test"; | ||
import consumers from 'stream/consumers'; | ||
|
||
type Channel = { id: string; name: string; display_name: string; }; | ||
|
||
let apiCtx: APIRequestContext; | ||
let channel: Channel; | ||
|
||
test.beforeEach(async ({ context, baseURL }) => { | ||
const cookies = await context.cookies(); | ||
const token = cookies.find(c => c.name === 'MMAUTHTOKEN'); | ||
|
||
expect(token?.value).toBeDefined(); | ||
|
||
apiCtx = await request.newContext({ | ||
baseURL, | ||
extraHTTPHeaders: { | ||
'Accept': 'application/json', | ||
'Authorization': `Bearer ${token?.value}`, | ||
'X-Requested-With': 'XMLHttpRequest', // without this you get "Invalid or expired session, please login again." | ||
} | ||
}); | ||
|
||
// poll channel list in case default channels haven't been created yet | ||
await expect(async () => { | ||
const channels = await apiCtx.get('/api/v4/channels') | ||
.then(res => res.json()); | ||
|
||
expect(channels.length).toBeGreaterThanOrEqual(1); | ||
|
||
channel = channels.find((c: Channel) => c.display_name === 'Town Square'); | ||
expect(channel).toBeDefined(); | ||
expect(channel.display_name).toBe('Town Square'); | ||
}).toPass({ | ||
timeout: 60_000, | ||
}); | ||
}); | ||
|
||
function randomMessage(extra: string = "") { | ||
return `hello universe ${Math.floor((Math.random() * 1000))}-C3!` + extra; | ||
} | ||
|
||
async function createPost(page: Page, data: { channel_id: string, message: string; file_ids?: string[] }) { | ||
const req = await apiCtx.post('/api/v4/posts', { | ||
data, | ||
}); | ||
|
||
expect(req).toBeOK(); | ||
|
||
const post = await req.json(); | ||
|
||
expect(post.id).toBeDefined(); | ||
expect(post.message).toBe(data.message); | ||
|
||
return post; | ||
} | ||
|
||
test("send a message", async ({ page }) => { | ||
const post = await createPost(page, { | ||
channel_id: channel.id, | ||
message: randomMessage(), | ||
}); | ||
|
||
await page.goto('/unicorns/channels/town-square'); | ||
|
||
const el = page.locator(`#post_${post.id}`); | ||
await expect(el).toContainText(post.message); | ||
}); | ||
|
||
test("send a message with attachment", async ({ page }) => { | ||
const file = { | ||
name: 'README.md', | ||
mimeType: 'text/plain', | ||
buffer: Buffer.from('# My Cool Project'), | ||
}; | ||
|
||
const upload = await apiCtx.fetch('/api/v4/files', { | ||
method: 'POST', | ||
multipart: { | ||
channel_id: channel.id, | ||
files: file, | ||
}, | ||
}); | ||
|
||
expect(upload).toBeOK(); | ||
|
||
const res = await upload.json(); | ||
|
||
expect(res.file_infos.length).toBe(1); | ||
expect(res.file_infos[0].name).toBe(file.name); | ||
|
||
const message = randomMessage('\ncheckout this attachment...'); | ||
const post = await createPost(page, { | ||
channel_id: channel.id, | ||
message, | ||
file_ids: [ res.file_infos[0].id ], | ||
}); | ||
|
||
await page.goto('/unicorns/channels/town-square'); | ||
|
||
const el = page.locator(`#post_${post.id}`); | ||
await expect(el).toContainText(post.message); | ||
|
||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "uds-package-mattermost", | ||
"license": "Apache-2.0", | ||
"devDependencies": { | ||
"@playwright/test": "^1.43.1", | ||
"@types/node": "^20.12.12", | ||
"typescript": "^5.4.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { defineConfig, devices } from '@playwright/test'; | ||
|
||
export const playwrightDir = '.playwright'; | ||
export const authFile = `${playwrightDir}/auth/user.json`; | ||
|
||
/** | ||
* See https://playwright.dev/docs/test-configuration. | ||
*/ | ||
export default defineConfig({ | ||
fullyParallel: true, | ||
forbidOnly: !!process.env.CI, // fail CI if you accidently leave `test.only` in source | ||
retries: process.env.CI ? 1 : 0, | ||
workers: 1, | ||
reporter: [ | ||
// Reporter to use. See https://playwright.dev/docs/test-reporters | ||
['html', { outputFolder: `${playwrightDir}/reports`, open: 'never' }], | ||
['json', { outputFile: `${playwrightDir}/reports/test-results.json`, open: 'never' }], | ||
['list'] | ||
], | ||
|
||
outputDir: `${playwrightDir}/output`, | ||
|
||
use: { | ||
baseURL: process.env.BASE_URL || 'https://chat.uds.dev', // for `await page.goto('/')` etc | ||
trace: 'on-first-retry', // collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer | ||
}, | ||
|
||
projects: [ | ||
{ name: 'setup', testMatch: /.*\.setup\.ts/ }, // authentication | ||
|
||
...[ | ||
'Desktop Chrome', | ||
'Desktop Firefox', | ||
].map((p) => ({ | ||
name: devices[p].defaultBrowserType, | ||
dependencies: ['setup'], | ||
use: { | ||
...devices[p], | ||
storageState: authFile, | ||
}, | ||
})), | ||
], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ | ||
"module": "commonjs", /* Specify what module code is generated. */ | ||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ | ||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ | ||
"strict": true, /* Enable all strict type-checking options. */ | ||
"skipLibCheck": true /* Skip type checking all .d.ts files. */ | ||
} | ||
} |