Playwright tests for file uploads (#33319)
* Refactor tests to use helper method for composer uploads. * Add drag and drop tests * lint * Add commentary * fixup test * More precise selector
This commit is contained in:
@@ -7,6 +7,8 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type Locator, type Page, expect } from "@playwright/test";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { basename } from "node:path";
|
||||
|
||||
import { Settings } from "./settings";
|
||||
import { Client } from "./client";
|
||||
@@ -156,6 +158,66 @@ export class ElementAppPage {
|
||||
return this.page.getByRole("menu");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the files on the composers file input, causing it to open the file
|
||||
* upload dialog.
|
||||
* @param location Should the main room input or the thread view input be used.
|
||||
*/
|
||||
public setComposerInputFiles(
|
||||
location: "room" | "thread",
|
||||
...params: Parameters<Locator["setInputFiles"]>
|
||||
): ReturnType<Locator["setInputFiles"]> {
|
||||
const input = this.page
|
||||
.locator(location === "room" ? ".mx_RoomView_body" : ".mx_RightPanel")
|
||||
.getByRole("region", { name: "Message composer" })
|
||||
.locator("input[type='file']");
|
||||
return input.setInputFiles(...params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the files on the composers file input, causing it to open the file
|
||||
* upload dialog, and then automaticlly submits the dialog that pops up which
|
||||
* causes the file to be uploaded.
|
||||
* @param location Should the main room input or the thread view input be used.
|
||||
*/
|
||||
public async composerUploadFiles(
|
||||
location: "room" | "thread",
|
||||
...params: Parameters<Locator["setInputFiles"]>
|
||||
): Promise<void> {
|
||||
await this.setComposerInputFiles(location, ...params);
|
||||
await this.page.locator(".mx_Dialog").getByRole("button", { name: "Upload" }).click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Drags a "file" into the specified composer and automatically uploads it.
|
||||
* @param location Should the drop target the main room or the thread.
|
||||
* @param path The path to the sample file so it can be read.
|
||||
* @param type The mimetype of the file.
|
||||
*/
|
||||
public async composerDragAndUploadFiles(location: "room" | "thread", path: string, type: string): Promise<void> {
|
||||
// Based on https://github.com/microsoft/playwright/issues/10667#issuecomment-2742123424
|
||||
// This read a file, encodes it into base64 and then sends it along to the page to be treated
|
||||
// as a DataTransfer (the mechanism for drag and dropped files).
|
||||
const buffer = await readFile(path);
|
||||
const name = basename(path);
|
||||
|
||||
const dataTransfer = await this.page.evaluateHandle(
|
||||
async ([buffer, name, type]) => {
|
||||
const dt = new DataTransfer();
|
||||
const file = new File([Uint8Array.fromBase64(buffer)], name, {
|
||||
type,
|
||||
});
|
||||
dt.items.add(file);
|
||||
return dt;
|
||||
},
|
||||
[buffer.toString("base64"), name, type],
|
||||
);
|
||||
await this.page.dispatchEvent(location === "room" ? ".mx_RoomView_body" : ".mx_ThreadPanel", "drop", {
|
||||
dataTransfer,
|
||||
});
|
||||
await this.page.locator(".mx_Dialog").getByRole("button", { name: "Upload" }).click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the space panel space button based on a name. The space
|
||||
* must be visible in the space panel
|
||||
|
||||
Reference in New Issue
Block a user