froth-webdriverio-framework 7.0.119-dev1.1 → 7.0.119-dev1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +245 -0
  2. package/allure-report-utils/allure-helper.js +226 -0
  3. package/allure-report-utils/froth-report.js +142 -0
  4. package/allure-report-utils/generate-allure-report.js +167 -0
  5. package/allure-report-utils/open-allure-report.js +97 -0
  6. package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success.png +0 -0
  7. package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success_2026-06-19T08-07-53-694Z.png +0 -0
  8. package/allure-screenshots/Recorded_Scripts_Recorded_test_steps_success_2026-06-19T08-10-50-605Z.png +0 -0
  9. package/allure-screenshots/action_001_setWindowSize_2026-06-19T08-10-35-850Z.png +0 -0
  10. package/allure-screenshots/action_001_url.png +0 -0
  11. package/allure-screenshots/action_002_click.png +0 -0
  12. package/allure-screenshots/action_002_url_2026-06-19T08-10-37-002Z.png +0 -0
  13. package/allure-screenshots/action_003_clearValue.png +0 -0
  14. package/allure-screenshots/action_003_setValue.png +0 -0
  15. package/allure-screenshots/action_003_waitForExist_2026-06-19T08-10-42-230Z.png +0 -0
  16. package/allure-screenshots/action_004_click.png +0 -0
  17. package/allure-screenshots/action_004_waitForExist_2026-06-19T08-10-42-353Z.png +0 -0
  18. package/allure-screenshots/action_005_clearValue.png +0 -0
  19. package/allure-screenshots/action_005_click_2026-06-19T08-10-43-186Z.png +0 -0
  20. package/allure-screenshots/action_005_setValue.png +0 -0
  21. package/allure-screenshots/action_006_click_2026-06-19T08-10-43-301Z.png +0 -0
  22. package/allure-screenshots/action_007_clearValue_2026-06-19T08-10-43-974Z.png +0 -0
  23. package/allure-screenshots/action_008_clearValue_2026-06-19T08-10-44-058Z.png +0 -0
  24. package/allure-screenshots/action_009_addValue_2026-06-19T08-10-44-559Z.png +0 -0
  25. package/allure-screenshots/action_010_addValue_2026-06-19T08-10-44-656Z.png +0 -0
  26. package/allure-screenshots/action_011_setValue_2026-06-19T08-10-44-779Z.png +0 -0
  27. package/allure-screenshots/action_012_setValue_2026-06-19T08-10-44-905Z.png +0 -0
  28. package/allure-screenshots/action_013_click_2026-06-19T08-10-45-787Z.png +0 -0
  29. package/allure-screenshots/action_014_click_2026-06-19T08-10-45-892Z.png +0 -0
  30. package/allure-screenshots/action_015_clearValue_2026-06-19T08-10-46-549Z.png +0 -0
  31. package/allure-screenshots/action_016_clearValue_2026-06-19T08-10-46-635Z.png +0 -0
  32. package/allure-screenshots/action_017_addValue_2026-06-19T08-10-46-868Z.png +0 -0
  33. package/allure-screenshots/action_018_addValue_2026-06-19T08-10-46-997Z.png +0 -0
  34. package/allure-screenshots/action_019_setValue_2026-06-19T08-10-47-080Z.png +0 -0
  35. package/allure-screenshots/action_020_setValue_2026-06-19T08-10-47-163Z.png +0 -0
  36. package/allure-screenshots/action_021_click_2026-06-19T08-10-47-377Z.png +0 -0
  37. package/allure-screenshots/action_022_click_2026-06-19T08-10-47-472Z.png +0 -0
  38. package/froth_configs/base.config.js +47 -3
  39. package/froth_configs/commonhook.js +53 -0
  40. package/froth_configs/local/mobile.config.js +57 -9
  41. package/froth_configs/local/web.config.js +139 -33
  42. package/froth_configs/screenshot-service.js +157 -0
  43. package/froth_configs/wdio.common.conf.js +112 -1
  44. package/package.json +62 -50
@@ -1,57 +1,163 @@
1
1
  module.exports = (bsCaps) => {
2
2
  const browserName = (bsCaps.browserName || 'chrome').toLowerCase();
3
3
 
4
- // Map browser names to their WebdriverIO services
5
- const browserServiceMap = {
6
- chrome: 'chromedriver',
7
- firefox: 'geckodriver',
8
- edge: 'edgedriver',
9
- ie: 'iedriver',
10
- 'internet explorer': 'iedriver',
11
- safari: 'safaridriver'
4
+ // Generate unique report directory using BROWSERSTACK_BUILD_NAME
5
+ const buildName = process.env.BROWSERSTACK_BUILD_NAME || 'local-build';
6
+ // Remove spaces and special characters from build name for folder name - use underscores
7
+ const cleanBuildName = buildName.replace(/[^a-zA-Z0-9_]/g, '_');
8
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('T')[0]; // YYYY-MM-DD format
9
+ const uniqueReportDir = `./reports/allure/${cleanBuildName}-${timestamp}`;
10
+
11
+ // Normalize browser names for WebDriver
12
+ const browserNameMap = {
13
+ chrome: 'chrome',
14
+ chromium: 'chrome',
15
+ firefox: 'firefox',
16
+ edge: 'MicrosoftEdge',
17
+ msedge: 'MicrosoftEdge',
18
+ 'microsoft edge': 'MicrosoftEdge',
19
+ safari: 'safari',
20
+ ie: 'internet explorer',
21
+ 'internet explorer': 'internet explorer',
22
+ 'internet-explorer': 'internet explorer'
12
23
  };
13
24
 
14
- const service = browserServiceMap[browserName] || 'chromedriver';
25
+ const normalizedBrowserName = browserNameMap[browserName] || 'chrome';
15
26
 
16
- const config = {
17
- services: [service]
18
- };
27
+ // Configure browser-specific capabilities
28
+ let capabilities;
29
+ let service;
19
30
 
20
- // Add browser-specific capabilities
21
- if (browserName === 'chrome') {
22
- config.capabilities = [{
31
+ if (normalizedBrowserName === 'chrome') {
32
+ capabilities = [{
23
33
  browserName: 'chrome',
24
34
  'goog:chromeOptions': {
25
- // args: browserVersion ? [`--version=${browserVersion}`] : []
35
+ args: [
36
+ '--no-sandbox',
37
+ '--disable-dev-shm-usage',
38
+ '--disable-gpu',
39
+ '--disable-web-security',
40
+ '--disable-features=VizDisplayCompositor'
41
+ ]
26
42
  }
27
43
  }];
28
- } else if (browserName === 'firefox') {
29
- config.capabilities = [{
44
+
45
+ // Use wdio-chromedriver-service - auto-downloads ChromeDriver at runtime
46
+ // No admin permission needed - downloads to node_modules/
47
+ service = ['chromedriver', {
48
+ // Automatically download ChromeDriver if not present
49
+ chromedriverOptions: {
50
+ // Check for ChromeDriver updates (set to false for faster startup)
51
+ checkForUpdates: true,
52
+ // Use latest ChromeDriver compatible with installed Chrome
53
+ // If false, uses version specified in package.json chromedriver dependency
54
+ autoDownload: true
55
+ }
56
+ }]
57
+
58
+ } else if (normalizedBrowserName === 'firefox') {
59
+ capabilities = [{
30
60
  browserName: 'firefox',
31
61
  'moz:firefoxOptions': {
32
- // Add Firefox-specific options if needed
62
+ //args: ['-headless'],
63
+ prefs: {
64
+ 'dom.webdriver.enabled': false,
65
+ 'useAutomationExtension': false
66
+ }
33
67
  }
34
68
  }];
35
- } else if (browserName === 'edge') {
36
- config.capabilities = [{
37
- browserName: 'MicrosoftEdge'
38
- }];
39
- } else if (browserName === 'safari') {
40
- config.capabilities = [{
41
- browserName: 'safari'
69
+
70
+ // Use wdio-geckodriver-service for Firefox
71
+ service = ['geckodriver', {
72
+ // Auto-download geckodriver if not present
73
+ geckodriverOptions: {
74
+ // Use the geckodriver from node_modules
75
+ // No need to download separately
76
+ }
42
77
  }];
43
- } else if (browserName === 'ie' || browserName === 'internet explorer') {
44
- config.capabilities = [{
45
- browserName: 'internet explorer'
78
+ } else if (normalizedBrowserName === 'MicrosoftEdge') {
79
+ capabilities = [{
80
+ browserName: 'MicrosoftEdge',
81
+ 'ms:edgeOptions': {
82
+ args: [
83
+ '--no-sandbox',
84
+ '--disable-dev-shm-usage',
85
+ '--disable-gpu'
86
+ ]
87
+ }
46
88
  }];
89
+
90
+ // EdgeDriver is included with Edge browser - no download needed
91
+ service = ['edgedriver'];
92
+
47
93
  } else {
48
94
  // Default to Chrome for unsupported browsers
49
- config.capabilities = [{
50
- browserName: 'chrome'
95
+ capabilities = [{
96
+ browserName: 'chrome',
97
+ 'goog:chromeOptions': {
98
+ args: ['--no-sandbox', '--disable-dev-shm-usage', '--disable-gpu']
99
+ }
100
+ }];
101
+
102
+ service = ['chromedriver', {
103
+ chromedriverOptions: {
104
+ checkForUpdates: true,
105
+ autoDownload: true
106
+ }
51
107
  }];
52
108
  }
53
109
 
54
- console.log(`🌐 Local execution configured for: ${browserName} using service: ${service}`);
110
+ const config = {
111
+ // Use direct WebDriver connection without Selenium Grid/Hub
112
+ // Opens Chrome/Firefox directly - no selenium-server
113
+ protocol: 'webdriver',
114
+
115
+ // Auto-download drivers service + real-time screenshot service
116
+ services: [
117
+ ...(service.length > 0 ? [service] : []),
118
+ // Real-time screenshot capture (works even if execution stopped mid-way)
119
+ [require('../screenshot-service').ScreenshotService]
120
+ ],
121
+
122
+ capabilities: capabilities,
123
+
124
+ // Allure Reporter Configuration
125
+ reporters: [
126
+ ['allure', {
127
+ outputDir: uniqueReportDir,
128
+ disableWebdriverStepsReporting: false, // Enable step reporting
129
+ disableWebdriverScreenshotsReporting: false, // Enable automatic screenshot capture
130
+ useCucumberStepReporter: false,
131
+ disableMochaHooks: false,
132
+ allureCode: true,
133
+ captureAllureScreenshots: true
134
+ }]
135
+ ],
136
+
137
+ // Auto-generate report after execution completes
138
+ onComplete: async function(exitCode, config, capabilities, results) {
139
+ const { execSync } = require('child_process');
140
+ const nodePath = require('path');
141
+ try {
142
+ // Add a small delay to ensure Allure finishes writing all files
143
+ await new Promise(resolve => setTimeout(resolve, 1000));
144
+
145
+ // Resolve script path relative to framework package (works from any CWD)
146
+ const scriptPath = nodePath.resolve(__dirname, '../../allure-report-utils/generate-allure-report.js');
147
+
148
+ console.log('\n🎯 Generating Allure report...');
149
+ execSync(`node "${scriptPath}"`, { stdio: 'inherit', cwd: process.cwd() });
150
+ console.log('✅ Report generation complete!');
151
+ } catch (error) {
152
+ console.error('❌ Error generating report:', error.message);
153
+ }
154
+ }
155
+ };
156
+
157
+ console.log(`🌐 Local execution configured for: ${normalizedBrowserName}`);
158
+ console.log(`📦 Browser drivers will auto-download to node_modules/ (no admin permission needed)`);
159
+ console.log(`📊 Allure results will be saved in: ${uniqueReportDir}`);
160
+ console.log(`💡 Report will be generated automatically after execution completes`);
55
161
 
56
162
  return config;
57
- };
163
+ };
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Froth Screenshot Service for WebDriverIO
3
+ * Captures screenshots in REAL-TIME:
4
+ * - After each KEY ACTION (click, input, navigation) - no duplicates
5
+ * - After each TEST (afterTest) - final state per test
6
+ * - Works even if execution is stopped mid-way
7
+ * - Deduplicates identical screenshots to avoid clutter
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const crypto = require('crypto');
13
+
14
+ class ScreenshotService {
15
+ constructor(options = {}) {
16
+ this.options = options;
17
+ this.screenshotDir = './allure-screenshots';
18
+ this.actionCounter = 0;
19
+ this.lastScreenshotHash = null;
20
+ this.lastActionTime = 0;
21
+ }
22
+
23
+ // Runs before test execution starts
24
+ async onPrepare() {
25
+ if (!fs.existsSync(this.screenshotDir)) {
26
+ fs.mkdirSync(this.screenshotDir, { recursive: true });
27
+ }
28
+ console.log('📸 Screenshot Service initialized - deduplicated real-time capture');
29
+ }
30
+
31
+ // Runs after EACH KEY ACTION - captures screenshot (with deduplication)
32
+ async afterCommand(commandName, args, result, error) {
33
+ // Only capture for local platform
34
+ if (process.env.PLATFORM !== 'local') {
35
+ return;
36
+ }
37
+
38
+ // Skip screenshot commands to avoid recursion
39
+ if (commandName === 'saveScreenshot' || commandName === 'takeScreenshot') {
40
+ return;
41
+ }
42
+
43
+ // ONLY capture these 3 key actions: navigation, click, input
44
+ const captureCommands = ['url', 'click', 'setValue'];
45
+
46
+ if (!captureCommands.includes(commandName)) {
47
+ return;
48
+ }
49
+
50
+ // Throttle: skip if last screenshot was less than 500ms ago (rapid commands)
51
+ const now = Date.now();
52
+ if (now - this.lastActionTime < 500) {
53
+ return;
54
+ }
55
+ this.lastActionTime = now;
56
+
57
+ try {
58
+ const allure = require('@wdio/allure-reporter').default;
59
+
60
+ // Take screenshot to memory (buffer) instead of file for dedup check
61
+ const screenshotBase64 = await browser.takeScreenshot();
62
+ const imageBuffer = Buffer.from(screenshotBase64, 'base64');
63
+
64
+ // Generate hash to detect duplicates
65
+ const hash = crypto.createHash('md5').update(imageBuffer).digest('hex');
66
+
67
+ // Skip if identical to last screenshot (duplicate)
68
+ if (hash === this.lastScreenshotHash) {
69
+ return;
70
+ }
71
+ this.lastScreenshotHash = hash;
72
+
73
+ this.actionCounter++;
74
+ const actionDesc = this.formatActionDescription(commandName, args);
75
+
76
+ // Save unique screenshot to file
77
+ const screenshotName = `action_${String(this.actionCounter).padStart(3, '0')}_${commandName}`;
78
+ const screenshotPath = path.join(this.screenshotDir, `${screenshotName}.png`);
79
+ fs.writeFileSync(screenshotPath, imageBuffer);
80
+
81
+ // Attach to Allure IMMEDIATELY (real-time)
82
+ allure.addAttachment(`📸 ${commandName} ${actionDesc}`.trim(), imageBuffer, 'image/png');
83
+ } catch (err) {
84
+ // Silent fail to avoid breaking tests
85
+ }
86
+ }
87
+
88
+ // Format action description for screenshot name
89
+ formatActionDescription(commandName, args) {
90
+ try {
91
+ if (commandName === 'url' && args && args[0]) {
92
+ const url = args[0].toString();
93
+ return `→ ${url.substring(0, 40)}`;
94
+ }
95
+ if (commandName === 'setValue' && args && args[1] !== undefined) {
96
+ return `(input "${args[1].toString().substring(0, 25)}")`;
97
+ }
98
+ if (commandName === 'addValue' && args && args[1] !== undefined) {
99
+ return `(added "${args[1].toString().substring(0, 25)}")`;
100
+ }
101
+ if (commandName === 'click' && args && args[0]) {
102
+ return `(${args[0].toString().substring(0, 40)})`;
103
+ }
104
+ return '';
105
+ } catch (e) {
106
+ return '';
107
+ }
108
+ }
109
+
110
+ // Runs after each test - captures final test screenshot
111
+ async afterTest(test, context, { error, result, passed, retries }) {
112
+ if (process.env.PLATFORM !== 'local') {
113
+ return;
114
+ }
115
+
116
+ try {
117
+ const allure = require('@wdio/allure-reporter').default;
118
+ const cleanTitle = test.title.replace(/[^a-zA-Z0-9]/g, '_');
119
+ const cleanParent = test.parent ? test.parent.replace(/[^a-zA-Z0-9]/g, '_') : 'test';
120
+
121
+ const status = passed ? 'success' : 'failure';
122
+
123
+ // Take screenshot to buffer
124
+ const screenshotBase64 = await browser.takeScreenshot();
125
+ const imageBuffer = Buffer.from(screenshotBase64, 'base64');
126
+
127
+ // Check for duplicate
128
+ const hash = crypto.createHash('md5').update(imageBuffer).digest('hex');
129
+ if (hash === this.lastScreenshotHash) {
130
+ // Reset for next test and skip
131
+ this.actionCounter = 0;
132
+ this.lastScreenshotHash = null;
133
+ return;
134
+ }
135
+
136
+ const screenshotName = `${cleanParent}_${cleanTitle}_${status}`;
137
+ const screenshotPath = path.join(this.screenshotDir, `${screenshotName}.png`);
138
+ fs.writeFileSync(screenshotPath, imageBuffer);
139
+
140
+ const attachmentName = passed ? '✅ Test Passed' : '❌ Test Failed';
141
+ allure.addAttachment(attachmentName, imageBuffer, 'image/png');
142
+ console.log(`📸 [Real-time] Test screenshot attached: ${status}`);
143
+
144
+ // Reset for next test
145
+ this.actionCounter = 0;
146
+ this.lastScreenshotHash = null;
147
+ } catch (error) {
148
+ console.error('❌ [Real-time] Error capturing test screenshot:', error.message);
149
+ }
150
+ }
151
+ }
152
+
153
+ // Export both as class and factory function
154
+ module.exports = {
155
+ ScreenshotService,
156
+ default: () => new ScreenshotService()
157
+ };
@@ -63,5 +63,116 @@ if (PLATFORM === 'browserstack' || PLATFORM === 'browserstacklocal') {
63
63
  }
64
64
 
65
65
 
66
- exports.config = deepmerge(baseConfig, envConfig(bsCaps));
66
+ // Debug logging
67
+ console.log('=== CONFIG MERGE DEBUG ===');
68
+ console.log('PLATFORM value:', PLATFORM);
69
+ console.log('baseConfig.afterEach exists:', !!baseConfig.afterEach);
70
+ console.log('envConfig type:', typeof envConfig);
71
+
72
+ // Get the env config but don't merge yet
73
+ const envConfigResult = envConfig(bsCaps);
74
+ console.log('envConfigResult.afterEach exists:', !!envConfigResult.afterEach);
75
+
76
+ // Merge the configs
77
+ const finalConfig = deepmerge(baseConfig, envConfigResult);
78
+
79
+ // Always preserve base config hooks for local platform
80
+ if (PLATFORM === 'local' && baseConfig.afterEach) {
81
+ console.log('Preserving baseConfig.afterEach for local platform');
82
+ finalConfig.afterEach = baseConfig.afterEach;
83
+ } else if (finalConfig.afterEach) {
84
+ console.log('Using envConfig afterEach');
85
+ } else {
86
+ console.log('No afterEach hook found in any config');
87
+ }
88
+
89
+ console.log('finalConfig.afterEach type:', typeof finalConfig.afterEach);
90
+ console.log('=== END CONFIG MERGE DEBUG ===');
91
+
92
+ // Add onComplete hook to attach screenshots to test results
93
+ const originalOnComplete = finalConfig.onComplete;
94
+ finalConfig.onComplete = async function(exitCode, config, capabilities, results) {
95
+ console.log('🎯 Attaching screenshots to test results...');
96
+
97
+ try {
98
+ const fs = require('fs');
99
+ const path = require('path');
100
+
101
+ // Find the most recent Allure results directory (where screenshots are saved)
102
+ const reportsBaseDir = './reports/allure';
103
+ if (fs.existsSync(reportsBaseDir)) {
104
+ const dirs = fs.readdirSync(reportsBaseDir)
105
+ .map(file => path.join(reportsBaseDir, file))
106
+ .filter(file => fs.statSync(file).isDirectory())
107
+ .sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
108
+
109
+ if (dirs.length > 0) {
110
+ const latestDir = dirs[0];
111
+ console.log(`📁 Report directory: ${latestDir}`);
112
+
113
+ // Find screenshots saved directly in the report directory
114
+ const screenshots = fs.readdirSync(latestDir)
115
+ .filter(file => file.endsWith('.png'))
116
+ .map(file => path.join(latestDir, file));
117
+
118
+ console.log(`📸 Found ${screenshots.length} screenshots in report folder`);
119
+
120
+ // Find test result files
121
+ const resultFiles = fs.readdirSync(latestDir)
122
+ .filter(file => file.endsWith('-result.json'));
123
+
124
+ console.log(`📋 Found ${resultFiles.length} test result files`);
125
+
126
+ // Attach a screenshot to each test result
127
+ resultFiles.forEach((resultFile, index) => {
128
+ try {
129
+ const resultPath = path.join(latestDir, resultFile);
130
+ const resultData = JSON.parse(fs.readFileSync(resultPath, 'utf8'));
131
+
132
+ // Add screenshot attachment
133
+ if (screenshots.length > 0) {
134
+ const screenshotIndex = Math.min(index, screenshots.length - 1);
135
+ const screenshotPath = screenshots[screenshotIndex];
136
+ const screenshotBuffer = fs.readFileSync(screenshotPath);
137
+
138
+ // Create attachment in the Allure directory
139
+ const attachmentName = `screenshot-${index}.png`;
140
+ const attachmentPath = path.join(latestDir, attachmentName);
141
+
142
+ fs.writeFileSync(attachmentPath, screenshotBuffer);
143
+
144
+ // Add attachment reference to test result
145
+ if (!resultData.attachments) {
146
+ resultData.attachments = [];
147
+ }
148
+
149
+ resultData.attachments.push({
150
+ name: 'Screenshot',
151
+ source: attachmentName,
152
+ type: 'image/png'
153
+ });
154
+
155
+ // Write updated result file
156
+ fs.writeFileSync(resultPath, JSON.stringify(resultData, null, 2));
157
+ console.log(`✅ Attached screenshot to: ${resultFile}`);
158
+ }
159
+ } catch (error) {
160
+ console.error(`❌ Error processing ${resultFile}:`, error.message);
161
+ }
162
+ });
163
+
164
+ console.log(`✅ Attached ${resultFiles.length} screenshots to test results`);
165
+ }
166
+ }
167
+ } catch (error) {
168
+ console.error('❌ Error in onComplete screenshot attachment:', error.message);
169
+ }
170
+
171
+ // Call original onComplete if it exists
172
+ if (typeof originalOnComplete === 'function') {
173
+ await originalOnComplete(exitCode, config, capabilities, results);
174
+ }
175
+ };
176
+
177
+ exports.config = finalConfig;
67
178
 
package/package.json CHANGED
@@ -1,51 +1,63 @@
1
- { "name": "froth-webdriverio-framework",
2
- "version": "7.0.119-dev1.1",
3
- "readme": "WebdriverIO Integration",
4
- "description": "WebdriverIO and BrowserStack App Automate",
5
- "license": "MIT",
6
-
7
- "scripts": {
8
- "lint": "eslint ."
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "https://github.com/RoboticoDigitalProjects/froth-webdriverio.git"
13
- },
14
- "keywords": [
15
- "webdriverio",
16
- "browserstack",
17
- "appium"
18
- ],
19
- "dependencies": {
20
-
21
- "@wdio/appium-service": "9.23.0",
22
- "@wdio/browserstack-service": "9.23.0",
23
- "@wdio/cli": "9.23.0",
24
- "@wdio/local-runner": "9.23.0",
25
- "@wdio/mocha-framework": "9.23.0",
26
- "@wdio/spec-reporter": "^9.20.0",
27
- "appium": "^3.1.2",
28
- "appium-uiautomator2-driver": "^6.7.8",
29
- "assert": "^2.1.0",
30
- "axios": "1.14.0",
31
- "browserstack-local": "^1.5.8",
32
- "chai": "^6.2.2",
33
- "crypto-js": "^4.2.0",
34
- "deepmerge": "^4.3.1",
35
- "ejs": "^4.0.1",
36
- "expect-webdriverio": "^4.13.0",
37
- "express": "^5.2.1",
38
- "form-data": "^4.0.5",
39
- "fs": "^0.0.1-security",
40
- "js-yaml": "^4.1.1",
41
- "mysql2": "^3.16.0",
42
- "node-fetch": "^3.3.2",
43
- "node-localstorage": "^3.0.5",
44
- "randexp": "^0.5.3",
45
- "ts-node": "^10.9.2",
46
- "typescript": "^5.9.3",
47
-
48
- "vm": "^0.1.0"
49
-
50
- }
1
+ {
2
+ "name": "froth-webdriverio-framework",
3
+ "version": "7.0.119-dev1.10",
4
+ "readme": "WebdriverIO Integration",
5
+ "description": "WebdriverIO and BrowserStack App Automate",
6
+ "license": "MIT",
7
+ "bin": {
8
+ "froth-report": "allure-report-utils/froth-report.js"
9
+ },
10
+ "scripts": {
11
+ "lint": "eslint .",
12
+ "test": "npm run test:allure && npm run report:generate",
13
+ "test:allure": "wdio run froth_configs/local/web.config.js",
14
+ "report:generate": "node allure-report-utils/generate-allure-report.js",
15
+ "report:open": "node allure-report-utils/open-allure-report.js"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/RoboticoDigitalProjects/froth-webdriverio.git"
20
+ },
21
+ "keywords": [
22
+ "webdriverio",
23
+ "browserstack",
24
+ "appium"
25
+ ],
26
+ "dependencies": {
27
+ "@wdio/appium-service": "9.23.0",
28
+ "@wdio/browserstack-service": "9.23.0",
29
+ "@wdio/cli": "9.23.0",
30
+ "@wdio/local-runner": "9.23.0",
31
+ "@wdio/mocha-framework": "9.23.0",
32
+ "@wdio/selenium-standalone-service": "^8.14.0",
33
+ "@wdio/spec-reporter": "^9.20.0",
34
+ "@wdio/allure-reporter": "^9.20.0",
35
+ "allure-commandline": "^2.30.0",
36
+ "appium": "^3.1.2",
37
+ "appium-uiautomator2-driver": "^6.7.8",
38
+ "assert": "^2.1.0",
39
+ "axios": "1.14.0",
40
+ "browserstack-local": "^1.5.8",
41
+ "chai": "^6.2.2",
42
+ "chromedriver": "^149.0.4",
43
+ "crypto-js": "^4.2.0",
44
+ "deepmerge": "^4.3.1",
45
+ "ejs": "^4.0.1",
46
+ "expect-webdriverio": "^4.13.0",
47
+ "express": "^5.2.1",
48
+ "form-data": "^4.0.5",
49
+ "fs": "^0.0.1-security",
50
+ "geckodriver": "^4.5.0",
51
+ "js-yaml": "^4.1.1",
52
+ "mysql2": "^3.16.0",
53
+ "node-fetch": "^3.3.2",
54
+ "node-localstorage": "^3.0.5",
55
+ "randexp": "^0.5.3",
56
+ "ts-node": "^10.9.2",
57
+ "typescript": "^5.9.3",
58
+ "vm": "^0.1.0",
59
+ "wdio-chromedriver-service": "^8.1.1",
60
+ "wdio-geckodriver-service": "^5.0.2"
61
+ }
62
+
51
63
  }