Migrate timeline.spec.ts from Cypress to Playwright (#12025)
* Migrate timeline.spec.ts from Cypress to Playwright Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Monospace font for timestamps Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * More expects Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
BIN
cypress/fixtures/element.png
Normal file
After Width: | Height: | Size: 17 KiB |
|
@ -26,7 +26,10 @@ export default defineConfig<TestOptions>({
|
|||
ignoreHTTPSErrors: true,
|
||||
video: "retain-on-failure",
|
||||
baseURL,
|
||||
permissions: ["clipboard-write", "clipboard-read"],
|
||||
permissions: ["clipboard-write", "clipboard-read", "microphone"],
|
||||
launchOptions: {
|
||||
args: ["--use-fake-ui-for-media-stream", "--use-fake-device-for-media-stream", "--mute-audio"],
|
||||
},
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
webServer: {
|
||||
|
|
1130
playwright/e2e/timeline/timeline.spec.ts
Normal file
|
@ -250,6 +250,10 @@ export const expect = baseExpect.extend({
|
|||
.mx_ReplyChain {
|
||||
border-left-color: var(--cpd-color-blue-1200) !important;
|
||||
}
|
||||
/* Use monospace font for timestamp for consistent mask width */
|
||||
.mx_MessageTimestamp {
|
||||
font-family: Inconsolata !important;
|
||||
}
|
||||
${options?.css ?? ""}
|
||||
`,
|
||||
})) as ElementHandle<Element>;
|
||||
|
|
|
@ -105,6 +105,14 @@ export class ElementAppPage {
|
|||
return this.page.locator(`${panelClass} .mx_MessageComposer`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the composer input field
|
||||
* @param isRightPanel whether to select the right panel composer, otherwise the main timeline composer
|
||||
*/
|
||||
public getComposerField(isRightPanel?: boolean): Locator {
|
||||
return this.getComposer(isRightPanel).locator("[contenteditable]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the message composer kebab menu
|
||||
* @param isRightPanel whether to select the right panel composer, otherwise the main timeline composer
|
||||
|
@ -155,4 +163,10 @@ export class ElementAppPage {
|
|||
await spotlight.open();
|
||||
return spotlight;
|
||||
}
|
||||
|
||||
public async scrollToBottom(page: Page): Promise<void> {
|
||||
await page
|
||||
.locator(".mx_ScrollPanel")
|
||||
.evaluate((scrollPanel) => scrollPanel.scrollTo(0, scrollPanel.scrollHeight));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ import type {
|
|||
IRoomDirectoryOptions,
|
||||
KnockRoomOpts,
|
||||
Visibility,
|
||||
UploadOpts,
|
||||
Upload,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { Credentials } from "../plugins/homeserver";
|
||||
|
||||
|
@ -293,6 +295,46 @@ export class Client {
|
|||
}, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {module:client.callback} callback Optional.
|
||||
* @return {Promise} Resolves: {} an empty object.
|
||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||
*/
|
||||
public async setDisplayName(name: string): Promise<{}> {
|
||||
const client = await this.prepareClient();
|
||||
return client.evaluate(async (cli: MatrixClient, name) => cli.setDisplayName(name), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @param {module:client.callback} callback Optional.
|
||||
* @return {Promise} Resolves: {} an empty object.
|
||||
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||
*/
|
||||
public async setAvatarUrl(url: string): Promise<{}> {
|
||||
const client = await this.prepareClient();
|
||||
return client.evaluate(async (cli: MatrixClient, url) => cli.setAvatarUrl(url), url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a file to the media repository on the homeserver.
|
||||
*
|
||||
* @param {object} file The object to upload. On a browser, something that
|
||||
* can be sent to XMLHttpRequest.send (typically a File). Under node.js,
|
||||
* a Buffer, String or ReadStream.
|
||||
*/
|
||||
public async uploadContent(file: Buffer, opts?: UploadOpts): Promise<Awaited<Upload["promise"]>> {
|
||||
const client = await this.prepareClient();
|
||||
return client.evaluate(
|
||||
async (cli: MatrixClient, { file, opts }) => cli.uploadContent(new Uint8Array(file), opts),
|
||||
{
|
||||
file: [...file],
|
||||
opts,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Boostraps cross-signing.
|
||||
*/
|
||||
|
|
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 8 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 5 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 10 KiB |