WebdriverIO中是否有ScenarioContext?如何跨测试场景存取值?
Great question! WebdriverIO doesn’t come with a built-in ScenarioContext like the one you have in Java, but it’s straightforward to build an equivalent (or even better) solution using JavaScript’s features. Let’s break this down step by step.
Implementing a Custom ScenarioContext
First, we’ll create a reusable module that mimics the HashMap-based context from your Java code. We’ll use a Map (JavaScript’s equivalent of HashMap) and export a singleton instance to ensure data is shared across all test files.
- Create a
scenarioContext.jsfile:
class ScenarioContext { constructor() { this.scenarioContext = new Map(); } // Set a value for a given key setContext(key, value) { this.scenarioContext.set(key.toString(), value); } // Retrieve a value by key getContext(key) { return this.scenarioContext.get(key.toString()); } // Check if a key exists in the context isContains(key) { return this.scenarioContext.has(key.toString()); } } // Export a singleton instance so all imports use the same context module.exports = new ScenarioContext();
- (Optional) Define a
Context"enum" to avoid magic strings (just like your JavaContextenum):
// contextKeys.js const Context = { USER_ID: 'USER_ID', AUTH_TOKEN: 'AUTH_TOKEN', CURRENT_PAGE: 'CURRENT_PAGE' }; module.exports = Context;
Using the Context in Your Tests
Now you can import this context into any test file to set and retrieve data across scenarios.
Example 1: Setting data in one test
// login.spec.js const scenarioContext = require('./scenarioContext'); const Context = require('./contextKeys'); describe('Login Flow', () => { it('should log in and store user ID', async () => { // Perform login steps... const userId = await $('[data-testid="user-id"]').getText(); // Store the user ID in the context scenarioContext.setContext(Context.USER_ID, userId); // Verify the key exists expect(scenarioContext.isContains(Context.USER_ID)).toBe(true); }); });
Example 2: Reusing data in another test
// userProfile.spec.js const scenarioContext = require('./scenarioContext'); const Context = require('./contextKeys'); describe('User Profile', () => { it('should retrieve stored user ID and validate profile', async () => { // Get the user ID from the context const userId = scenarioContext.getContext(Context.USER_ID); // Use the ID to navigate to the profile page await browser.url(`/profile/${userId}`); // Validate the profile displays the correct ID const displayedId = await $('[data-testid="profile-user-id"]').getText(); expect(displayedId).toBe(userId); }); });
Handling Parallel Test Execution
If you run tests in parallel, the singleton ScenarioContext will cause data leaks between test threads (since Node.js modules are process-wide). For this case, use WebdriverIO’s built-in browser.sharedStore (available in v7+), which is isolated to each browser instance:
// Setting data with sharedStore await browser.sharedStore.set(Context.USER_ID, userId); // Retrieving data const userId = await browser.sharedStore.get(Context.USER_ID); // Checking if a key exists const hasUserId = await browser.sharedStore.has(Context.USER_ID);
This ensures each test run gets its own isolated context, preventing cross-test contamination.
内容的提问来源于stack exchange,提问作者Mitali S

