Automated testing framework for uni-app projects enabling cross-platform testing across H5, WeChat mini-programs, and mobile apps
npx @tessl/cli install tessl/npm-dcloudio--uni-automator@2.0.0Uni Automator is an automated testing framework specifically designed for uni-app applications, enabling developers to programmatically interact with and test their cross-platform applications across multiple deployment targets including WeChat mini-programs, H5 web applications, and native mobile apps.
npm install @dcloudio/uni-automator --save-devconst automator = require("@dcloudio/uni-automator");For ES modules:
import automator from "@dcloudio/uni-automator";const automator = require("@dcloudio/uni-automator");
describe("My App Tests", () => {
let program;
let page;
beforeAll(async () => {
// Launch the automation framework
program = await automator.launch({
platform: "h5", // or "mp-weixin", "app-plus"
projectPath: "/path/to/uni-app-project"
});
// Navigate to initial page
page = await program.reLaunch("/pages/index/index");
await page.waitFor(1000);
});
it("should interact with elements", async () => {
// Find and interact with elements
const button = await page.$(".my-button");
await button.tap();
// Verify results
const text = await button.text();
expect(text).toBe("Expected Text");
});
afterAll(async () => {
await program.close();
});
});Uni Automator is built around several key components:
Program class) for application-wide operationsPage class) representing app screens/pagesElement classes) for DOM manipulation and testingCore functionality for initializing and configuring the automation testing environment across different platforms.
/**
* Launch the automation testing environment
* @param options - Platform and project configuration
* @returns Promise resolving to Program instance
*/
function launch(options: LaunchOptions): Promise<Program>;
interface LaunchOptions {
platform: "h5" | "mp-weixin" | "app-plus" | "mp-baidu";
projectPath?: string;
cliPath?: string;
timeout?: number;
compile?: boolean;
silent?: boolean;
h5?: H5Options;
"app-plus"?: AppPlusOptions;
"mp-weixin"?: WeChatOptions;
}Main interface for controlling the uni-app application, including navigation, system integration, and testing utilities.
class Program {
// Navigation methods
navigateTo(url: string): Promise<Page>;
redirectTo(url: string): Promise<Page>;
navigateBack(): Promise<Page>;
reLaunch(url: string): Promise<Page>;
switchTab(url: string): Promise<Page>;
// Page management
pageStack(): Promise<Page[]>;
currentPage(): Promise<Page>;
// System integration
systemInfo(): Promise<SystemInfo>;
callUniMethod(method: string, ...args: any[]): Promise<any>;
// Testing utilities
screenshot(options?: ScreenshotOptions): Promise<string>;
exposeFunction(name: string, fn: Function): Promise<void>;
pageScrollTo(scrollTop: number): Promise<void>;
// API mocking
mockUniMethod(method: string, implementation?: any, ...args: any[]): Promise<void>;
restoreUniMethod(method: string): Promise<void>;
// Code execution
evaluate(fn: Function, ...args: any[]): Promise<any>;
// WeChat specific
remote(autoconnect?: boolean): Promise<void>;
testAccounts(): Promise<TestAccount[]>;
// Lifecycle
close(): Promise<void>;
teardown(): Promise<void>;
disconnect(): Promise<void>;
}Interface for interacting with individual pages/screens in the application, including element selection and page data manipulation.
class Page {
// Element selection
$(selector: string): Promise<Element | null>;
$$(selector: string): Promise<Element[]>;
// Page data
data(path?: string): Promise<any>;
setData(data: object): Promise<void>;
callMethod(method: string, ...args: any[]): Promise<any>;
// Page information
size(): Promise<{width: number, height: number}>;
scrollTop(): Promise<number>;
// Waiting and timing
waitFor(condition: number | string | Function): Promise<void>;
}Comprehensive element interaction capabilities for testing UI components, form inputs, and user interactions.
class Element {
// Element information
text(): Promise<string>;
attribute(name: string): Promise<string>;
value(): Promise<any>;
property(name: string): Promise<any>;
// Element interaction
tap(): Promise<void>;
longpress(): Promise<void>;
trigger(event: string, detail?: any): Promise<void>;
// Specialized element methods vary by component type
}Uni Automator provides seamless Jest integration through custom environment and teardown scripts:
// jest.config.js
module.exports = {
globalTeardown: '@dcloudio/uni-automator/dist/teardown.js',
testEnvironment: '@dcloudio/uni-automator/dist/environment.js',
testEnvironmentOptions: {
platform: 'h5',
projectPath: process.cwd(),
// Other launch options
}
};With Jest integration, the automator instance is automatically available:
describe('App Tests', () => {
it('should work with Jest environment', async () => {
// program is automatically available
const page = await program.currentPage();
const element = await page.$('.button');
await element.tap();
});
});interface LaunchOptions {
platform: "h5" | "mp-weixin" | "app-plus" | "mp-baidu";
projectPath?: string;
cliPath?: string;
timeout?: number;
compile?: boolean;
silent?: boolean;
host?: string;
port?: number;
h5?: H5Options;
"app-plus"?: AppPlusOptions;
"mp-weixin"?: WeChatOptions;
"mp-baidu"?: BaiduOptions;
}
interface SystemInfo {
platform: string;
system: string;
version: string;
screenWidth: number;
screenHeight: number;
windowWidth: number;
windowHeight: number;
pixelRatio: number;
statusBarHeight: number;
safeArea: {
left: number;
right: number;
top: number;
bottom: number;
width: number;
height: number;
};
}
interface ScreenshotOptions {
path?: string;
fullPage?: boolean;
}
interface H5Options {
url?: string;
options?: {
headless?: boolean;
executablePath?: string;
defaultViewport?: {
width: number;
height: number;
};
[key: string]: any;
};
}
interface AppPlusOptions {
android?: {
executablePath: string;
};
ios?: {
id: string;
executablePath: string;
};
}
interface WeChatOptions {
port?: number;
account?: string;
args?: string;
cwd?: string;
launch?: boolean;
teardown?: "disconnect" | "close";
remote?: boolean;
executablePath?: string;
}
interface BaiduOptions {
port?: number;
args?: string;
cwd?: string;
launch?: boolean;
teardown?: "disconnect" | "close";
remote?: boolean;
executablePath?: string;
}
interface TestAccount {
account: string;
nickName: string;
avatar: string;
}