
Research
/Security News
9 Malicious NuGet Packages Deliver Time-Delayed Destructive Payloads
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.
playwright-m365-helpers
Advanced tools
A set of helpers for creating E2E tests for your Microsoft 365 projects using Playwright
This repository contains a set of Playwright helpers for Microsoft 365 projects.
npm i playwright-m365-helpers
Create a new login.setup.ts file in your tests folder and add the following code:
import { test as setup } from "@playwright/test";
import { login } from 'playwright-m365-helpers';
const AuthFile = "playwright/.auth/user.json";
setup("authenticate", async ({ page }) => {
await login(
page,
process.env.M365_PAGE_URL,
process.env.M365_USERNAME,
process.env.M365_PASSWORD,
process.env.M365_OTP_SECRET // Optional
);
await page.context().storageState({ path: AuthFile });
});
[!NOTE] In case of using Time-based One-Time Password (TOTP) for two-factor authentication, you can provide the secret key as the fourth parameter. To know more about signing in with TOTP, check the automating Microsoft 365 login with multi-factor authentication in Playwright tests article.
Create a new project in the playwright.config.ts file with the following code:
import { defineConfig } from "@playwright/test";
export default defineConfig({
...
projects: [
{
name: "setup",
testMatch: /login.setup.ts/,
},
{
name: "chromium",
use: {
storageState: "playwright/.auth/user.json",
},
dependencies: ["setup"], // This will run the setup project before the chromium project
},
],
});
There are various helpers for Power Platform projects:
getAppFrame - Get the iframe of the Power Platform app
import { getAppFrame } from 'playwright-m365-helpers';
test("Check if canvas is loaded", async () => {
await getAppFrame(page);
});
getControlByName - Get the control by name
import { getAppFrame, getControlByName } from 'playwright-m365-helpers';
test("Check if control is loaded", async () => {
const appFrame = await getAppFrame(page);
const control = getControlByName(appFrame, "controlName");
await expect(control).toBeVisible();
});
getControlPart - Get the control by its part name
import { getAppFrame, getControlPart } from 'playwright-m365-helpers';
test("Check if control part can be retrieved", async () => {
const appFrame = await getAppFrame(page);
const galleryItems = getControlPart(appFrame, "gallery-item");
await expect(galleryItems).toHaveCount(2);
});
getButton - Get the button by name
import { getAppFrame, getButton } from 'playwright-m365-helpers';
test("Check if button is loaded", async () => {
const appFrame = await getAppFrame(page);
const button = getButton(appFrame, "buttonName");
await expect(button).toBeVisible();
await button.click();
});
getDropdown - Get the dropdown by name
import { getAppFrame, getDropdown } from 'playwright-m365-helpers';
test("Check if dropdown is loaded", async () => {
const appFrame = await getAppFrame(page);
const dropdown = getDropdown(appFrame, "dropdownName");
await expect(dropdown).toBeVisible();
});
selectDropdownOption - Select the dropdown option by its value
import { getAppFrame, getDropdown, selectDropdownOption } from 'playwright-m365-helpers';
test("Check if dropdown option is selected", async () => {
const appFrame = await getAppFrame(page);
const dropdown = getDropdown(appFrame, "dropdownName");
await selectDropdownOption(appFrame, dropdown, "dropdown value");
await expect(dropdown).toHaveText(/dropdown value/);
});
getGalleryItems - Get the gallery items
import { getAppFrame, getControlPart } from 'playwright-m365-helpers';
test("Check if we can retrieve the gallery items", async () => {
const appFrame = await getAppFrame(page);
const gallery = getControlByName(appFrame, "galleryName");
const galleryItems = getGalleryItems(gallery);
await expect(galleryItems).toHaveCount(2);
});
getInput - Get the input by name
import { getAppFrame, getInput } from 'playwright-m365-helpers';
test("Check if input is loaded", async () => {
const appFrame = await getAppFrame(page);
// Single line input
const input = getInput(appFrame, "inputName");
await expect(input).toBeVisible();
await input.fill("Hello World");
// Multi-line input
const multiLineInput = getInput(appFrame, "multiLineInputName", true);
await expect(multiLineInput).toBeVisible();
await multiLineInput.fill("Hello World");
});
getLabel - Get the label by name
import { getAppFrame, getLabel } from 'playwright-m365-helpers';
test("Check if label is loaded", async () => {
const appFrame = await getAppFrame(page);
const input = getLabel(appFrame, "labelName");
await expect(input).toHaveText(/Label text/);
});
getRadio - Get the radio by name
import { getAppFrame, getRadio } from 'playwright-m365-helpers';
test("Check if radio is loaded", async () => {
const appFrame = await getAppFrame(page);
const radio = getRadio(appFrame, "radioName");
await expect(radio).toBeVisible();
});
selectRadioOption - Select the radio option by its value
import { getAppFrame, getRadio, selectRadioOption } from 'playwright-m365-helpers';
test("Select a radio option", async () => {
const appFrame = await getAppFrame(page);
const radio = getRadio(appFrame, "radioName");
await selectRadioOption(radio, "radio value");
});
getRadioOptions - Get the radio option(s)
import { getAppFrame, getRadio, getRadioOptions, selectRadioOption } from 'playwright-m365-helpers';
test("Check if radio options are loaded", async () => {
const appFrame = await getAppFrame(page);
const radio = getRadio(appFrame, "radioName");
await selectRadioOption(radio, "radio value");
const selectedOption = await getRadioOptions(frame, radio, true);
await expect(selectedOption).toHaveText(/radio value/);
});
getScreen - Get the screen by name
import { getAppFrame, getScreen } from 'playwright-m365-helpers';
test("Check if screen is loaded", async () => {
const appFrame = await getAppFrame(page);
const screen = getScreen(appFrame, "screenName");
await expect(screen).toBeVisible();
});
getToggle - Get the toggle by name
import { getAppFrame, getToggle } from 'playwright-m365-helpers';
test("Check if toggle is loaded", async () => {
const appFrame = await getAppFrame(page);
const toggle = getToggle(appFrame, "toggleName");
await expect(toggle).toBeVisible();
await toggle.click();
await expect(toggle).toHaveAttribute("aria-checked", "true");
});
In order to use the API helpers, you need to know the Power Platform connector ID. You can find this ID if you are going to your Power Platform connections page, and click on the connector you want to use. The connector ID is part of the URL.
https://make.powerapps.com/environments/<environment>/connections/<connector ID>/details
Example:
In the following URL:
https://make.powerapps.com/environments/12345678-1234-1234-1234-123456789012/connections/shared_sharepointonline/4aee3a63496d4e3f998c3910ba712bf2/details
The connector ID is shared_sharepointonline/4aee3a63496d4e3f998c3910ba712bf2.
The following API helpers are available:
mockConnector - Mock the Power Platform connector
import { mockConnector } from 'playwright-m365-helpers';
test("Mock the connector", async () => {
// Mock the connector with a GET request
await mockConnector(page, "connectorId", "connectorResponse");
// Mock the connector its POST event + status code
await mockConnector(page, "connectorId", "connectorResponse", "POST", 201;
});
waitForConnectorRequest - Wait for the connector request to be made
import { waitForConnectorRequest } from 'playwright-m365-helpers';
test("Wait for the connector request", async () => {
// Wait for the connector GET request
await waitForConnectorRequest(page, "connectorId");
// Wait for the connector POST request
await waitForConnectorRequest(page, "connectorId", "POST");
});
waitForConnectorResponse - Wait for the connector response to be received
import { waitForConnectorResponse } from 'playwright-m365-helpers';
test("Wait for the connector response", async () => {
// Wait for the connector GET response
await waitForConnectorResponse(page, "connectorId");
// Wait for the connector POST response
await waitForConnectorResponse(page, "connectorId", "POST");
});
[0.0.3] - 2024-11-06
getScreen locator function in the Power PlatformgetInput locator functionmockConnector, waitForConnectorRequest, and waitForConnectorResponse functionsmockConnector functionFAQs
A set of helpers for creating E2E tests for your Microsoft 365 projects using Playwright
The npm package playwright-m365-helpers receives a total of 405 weekly downloads. As such, playwright-m365-helpers popularity was classified as not popular.
We found that playwright-m365-helpers demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.