forked from trent_larson/crowd-funder-for-time-pwa
feat(ios-testing): Enhance deeplink testing and error handling
- Improve test data generation and validation - Add detailed logging of generated test data - Implement robust validation of required fields - Use ts-node script for test data generation - Add fallback data generation with validation - Enhance deeplink testing UX - Add interactive prompts between tests - Display detailed test progress and next steps - Improve error handling and test skip logic - Add comprehensive logging throughout test execution - Improve DeepLinkErrorView - Add detailed error information display - Show debug information for parameters and queries - Enhance UI with better styling and layout - Add safe area spacing for iOS - Refactor deeplink handling - Standardize route definitions - Improve parameter validation - Add better error logging
This commit is contained in:
@@ -40,7 +40,21 @@
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const { join } = require('path');
|
||||
const { existsSync, mkdirSync, appendFileSync, readFileSync, writeFileSync } = require('fs');
|
||||
const { existsSync, mkdirSync, appendFileSync, readFileSync, writeFileSync, readdirSync, statSync, accessSync } = require('fs');
|
||||
const readline = require('readline');
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
const { constants } = require('fs');
|
||||
|
||||
const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
|
||||
|
||||
// Make sure to close readline at the end
|
||||
process.on('SIGINT', () => {
|
||||
rl.close();
|
||||
process.exit();
|
||||
});
|
||||
|
||||
// Format date as YYYY-MM-DD-HHMMSS
|
||||
const getLogFileName = () => {
|
||||
@@ -316,122 +330,84 @@ const verifyXcodeInstallation = (log) => {
|
||||
|
||||
// Generate test data using generate_data.ts
|
||||
const generateTestData = async (log) => {
|
||||
log('🔄 Generating test data...');
|
||||
log('\n🔍 DEBUG: Starting test data generation...');
|
||||
|
||||
// Check if test-scripts directory exists
|
||||
if (!existsSync('test-scripts')) {
|
||||
log('⚠️ test-scripts directory not found');
|
||||
log('⚠️ Current directory: ' + process.cwd());
|
||||
|
||||
// List directories to help debug
|
||||
const { readdirSync } = require('fs');
|
||||
log('📂 Directories in current path:');
|
||||
try {
|
||||
const files = readdirSync('.');
|
||||
files.forEach(file => {
|
||||
const isDir = existsSync(file) && require('fs').statSync(file).isDirectory();
|
||||
log(`${isDir ? '📁' : '📄'} ${file}`);
|
||||
});
|
||||
} catch (err) {
|
||||
log(`⚠️ Error listing directory: ${err.message}`);
|
||||
}
|
||||
} else {
|
||||
log('✅ Found test-scripts directory');
|
||||
|
||||
// Check if generate_data.ts exists
|
||||
if (existsSync('test-scripts/generate_data.ts')) {
|
||||
log('✅ Found generate_data.ts');
|
||||
} else {
|
||||
log('⚠️ generate_data.ts not found in test-scripts directory');
|
||||
|
||||
// List files in test-scripts to help debug
|
||||
const { readdirSync } = require('fs');
|
||||
log('📂 Files in test-scripts:');
|
||||
try {
|
||||
const files = readdirSync('test-scripts');
|
||||
files.forEach(file => {
|
||||
log(`📄 ${file}`);
|
||||
});
|
||||
} catch (err) {
|
||||
log(`⚠️ Error listing test-scripts: ${err.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check directory structure
|
||||
log('📁 Current directory:', process.cwd());
|
||||
log('📁 Directory contents:', require('fs').readdirSync('.'));
|
||||
|
||||
// Create .generated directory if it doesn't exist
|
||||
if (!existsSync('.generated')) {
|
||||
log('📁 Creating .generated directory');
|
||||
mkdirSync('.generated', { recursive: true });
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// Try to generate test data using the script
|
||||
log('🔄 Running test data generation script...');
|
||||
log('🔄 Attempting to run generate_data.ts...');
|
||||
execSync('npx ts-node test-scripts/generate_data.ts', { stdio: 'inherit' });
|
||||
log('✅ Test data generation script completed');
|
||||
log('✅ Test data generation completed');
|
||||
|
||||
// Verify the generated files exist
|
||||
// Verify and log generated files content
|
||||
const requiredFiles = [
|
||||
'.generated/test-env.json',
|
||||
'.generated/claim_details.json',
|
||||
'.generated/contacts.json'
|
||||
];
|
||||
|
||||
log('🔍 Verifying generated files:');
|
||||
log('\n📝 Verifying generated files:');
|
||||
for (const file of requiredFiles) {
|
||||
if (!existsSync(file)) {
|
||||
log(`⚠️ Required file ${file} was not generated`);
|
||||
throw new Error(`Required file ${file} was not generated`);
|
||||
log(`❌ Missing file: ${file}`);
|
||||
} else {
|
||||
log(`✅ ${file} exists`);
|
||||
const content = readFileSync(file, 'utf8');
|
||||
log(`\n📄 Content of ${file}:`);
|
||||
log(content);
|
||||
try {
|
||||
const parsed = JSON.parse(content);
|
||||
if (file.includes('test-env.json')) {
|
||||
log('🔑 CONTACT1_DID in test-env:', parsed.CONTACT1_DID);
|
||||
}
|
||||
if (file.includes('contacts.json')) {
|
||||
log('👥 First contact DID:', parsed[0]?.did);
|
||||
}
|
||||
} catch (e) {
|
||||
log(`❌ Error parsing ${file}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
log(`⚠️ Failed to generate test data: ${error.message}`);
|
||||
log(`\n⚠️ Test data generation failed: ${error.message}`);
|
||||
log('⚠️ Creating fallback test data...');
|
||||
|
||||
// Create minimal fallback test data
|
||||
// Create fallback data with detailed logging
|
||||
const fallbackTestEnv = {
|
||||
"CONTACT1_DID": "did:example:123456789",
|
||||
"CONTACT1_DID": "did:ethr:0x35A71Ac3fA0A4D5a4903f10F0f7A3ac4034FaB5B",
|
||||
"APP_URL": "https://app.timesafari.example"
|
||||
};
|
||||
|
||||
const fallbackClaimDetails = {
|
||||
"claim_id": "claim_12345",
|
||||
"title": "Test Claim",
|
||||
"description": "This is a test claim"
|
||||
};
|
||||
|
||||
const fallbackContacts = [
|
||||
{
|
||||
"id": "contact1",
|
||||
"name": "Test Contact",
|
||||
"did": "did:example:123456789"
|
||||
"did": "did:ethr:0x35A71Ac3fA0A4D5a4903f10F0f7A3ac4034FaB5B"
|
||||
}
|
||||
];
|
||||
|
||||
// Use writeFileSync to overwrite any existing files
|
||||
const { writeFileSync } = require('fs');
|
||||
log('\n📝 Writing fallback data:');
|
||||
log('TestEnv:', JSON.stringify(fallbackTestEnv, null, 2));
|
||||
log('Contacts:', JSON.stringify(fallbackContacts, null, 2));
|
||||
|
||||
writeFileSync('.generated/test-env.json', JSON.stringify(fallbackTestEnv, null, 2));
|
||||
writeFileSync('.generated/claim_details.json', JSON.stringify(fallbackClaimDetails, null, 2));
|
||||
writeFileSync('.generated/contacts.json', JSON.stringify(fallbackContacts, null, 2));
|
||||
|
||||
log('✅ Fallback test data created');
|
||||
|
||||
// Verify files were created
|
||||
const requiredFiles = [
|
||||
'.generated/test-env.json',
|
||||
'.generated/claim_details.json',
|
||||
'.generated/contacts.json'
|
||||
];
|
||||
|
||||
log('🔍 Verifying fallback files:');
|
||||
for (const file of requiredFiles) {
|
||||
if (!existsSync(file)) {
|
||||
log(`⚠️ Failed to create ${file}`);
|
||||
} else {
|
||||
log(`✅ Created ${file}`);
|
||||
}
|
||||
// Verify fallback data was written
|
||||
log('\n🔍 Verifying fallback data:');
|
||||
try {
|
||||
const writtenTestEnv = JSON.parse(readFileSync('.generated/test-env.json', 'utf8'));
|
||||
const writtenContacts = JSON.parse(readFileSync('.generated/contacts.json', 'utf8'));
|
||||
log('Written TestEnv:', writtenTestEnv);
|
||||
log('Written Contacts:', writtenContacts);
|
||||
} catch (e) {
|
||||
log('❌ Error verifying fallback data:', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -535,6 +511,96 @@ const runIosApp = async (log, simulator) => {
|
||||
log('✅ App launched successfully');
|
||||
};
|
||||
|
||||
const validateTestData = (log) => {
|
||||
log('\n=== VALIDATING TEST DATA ===');
|
||||
|
||||
const generateFreshTestData = () => {
|
||||
log('\n🔄 Generating fresh test data...');
|
||||
try {
|
||||
// Ensure .generated directory exists
|
||||
if (!existsSync('.generated')) {
|
||||
mkdirSync('.generated', { recursive: true });
|
||||
}
|
||||
|
||||
// Execute the generate_data.ts script synchronously
|
||||
log('Running generate_data.ts...');
|
||||
execSync('npx ts-node test-scripts/generate_data.ts', {
|
||||
stdio: 'inherit',
|
||||
encoding: 'utf8'
|
||||
});
|
||||
|
||||
// Read and validate the generated files
|
||||
const testEnvPath = '.generated/test-env.json';
|
||||
const contactsPath = '.generated/contacts.json';
|
||||
|
||||
if (!existsSync(testEnvPath) || !existsSync(contactsPath)) {
|
||||
throw new Error('Generated files not found after running generate_data.ts');
|
||||
}
|
||||
|
||||
const testEnv = JSON.parse(readFileSync(testEnvPath, 'utf8'));
|
||||
const contacts = JSON.parse(readFileSync(contactsPath, 'utf8'));
|
||||
|
||||
// Validate required fields
|
||||
if (!testEnv.CONTACT1_DID) {
|
||||
throw new Error('CONTACT1_DID missing from generated test data');
|
||||
}
|
||||
|
||||
log('Generated test data:', {
|
||||
testEnv: testEnv,
|
||||
contacts: contacts
|
||||
});
|
||||
|
||||
return { testEnv, contacts };
|
||||
} catch (error) {
|
||||
log('❌ Test data generation failed:', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
// Try to read existing data or generate fresh data
|
||||
const testEnvPath = '.generated/test-env.json';
|
||||
const contactsPath = '.generated/contacts.json';
|
||||
|
||||
let testData;
|
||||
|
||||
// If either file is missing or invalid, generate fresh data
|
||||
if (!existsSync(testEnvPath) || !existsSync(contactsPath)) {
|
||||
testData = generateFreshTestData();
|
||||
} else {
|
||||
try {
|
||||
const testEnv = JSON.parse(readFileSync(testEnvPath, 'utf8'));
|
||||
const contacts = JSON.parse(readFileSync(contactsPath, 'utf8'));
|
||||
|
||||
// Validate required fields
|
||||
if (!testEnv.CLAIM_ID || !testEnv.CONTACT1_DID) {
|
||||
log('⚠️ Existing test data missing required fields, regenerating...');
|
||||
testData = generateFreshTestData();
|
||||
} else {
|
||||
testData = { testEnv, contacts };
|
||||
}
|
||||
} catch (error) {
|
||||
log('⚠️ Error reading existing test data, regenerating...');
|
||||
testData = generateFreshTestData();
|
||||
}
|
||||
}
|
||||
|
||||
// Final validation of data
|
||||
if (!testData.testEnv.CLAIM_ID || !testData.testEnv.CONTACT1_DID) {
|
||||
throw new Error('Test data validation failed even after generation');
|
||||
}
|
||||
|
||||
log('✅ Test data validated successfully');
|
||||
log('📄 Test Environment:', JSON.stringify(testData.testEnv, null, 2));
|
||||
|
||||
return testData;
|
||||
|
||||
} catch (error) {
|
||||
log(`❌ Test data validation failed: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Run deeplink tests
|
||||
* Optionally tests deeplinks if the test data is available
|
||||
@@ -543,77 +609,66 @@ const runIosApp = async (log, simulator) => {
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
const runDeeplinkTests = async (log) => {
|
||||
log('🔗 Starting deeplink tests...');
|
||||
log('\n=== Starting Deeplink Tests ===');
|
||||
|
||||
// Import readline module for user input
|
||||
const readline = require('readline');
|
||||
|
||||
// Create readline interface
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
// Promisify the question method
|
||||
const question = (query) => new Promise(resolve => rl.question(query, resolve));
|
||||
|
||||
// Register URL scheme if needed
|
||||
checkAndRegisterUrlScheme(log);
|
||||
|
||||
// Check if test data files exist first
|
||||
const requiredFiles = [
|
||||
'.generated/test-env.json',
|
||||
'.generated/claim_details.json',
|
||||
'.generated/contacts.json'
|
||||
];
|
||||
|
||||
for (const file of requiredFiles) {
|
||||
if (!existsSync(file)) {
|
||||
log(`⚠️ Required file ${file} does not exist`);
|
||||
log('⚠️ Skipping deeplink tests');
|
||||
rl.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if our app is actually running in the simulator
|
||||
log('🔍 Checking if app is currently running in simulator...');
|
||||
// Validate test data before proceeding
|
||||
let testEnv, contacts;
|
||||
try {
|
||||
const runningApps = execSync('xcrun simctl listapps booted').toString();
|
||||
const appIdentifier = getAppIdentifier();
|
||||
|
||||
if (!runningApps.includes(appIdentifier)) {
|
||||
log('⚠️ The app does not appear to be running in the simulator.');
|
||||
const shouldLaunch = await question('Would you like to launch the app now? (y/n): ');
|
||||
|
||||
if (shouldLaunch.toLowerCase() === 'y' || shouldLaunch.toLowerCase() === 'yes') {
|
||||
// Try launching the app again
|
||||
log('🚀 Launching app in simulator...');
|
||||
const simulatorInfo = JSON.parse(execSync('xcrun simctl list -j devices booted').toString());
|
||||
const booted = Object.values(simulatorInfo.devices)
|
||||
.flat()
|
||||
.find(device => device.state === 'Booted');
|
||||
|
||||
if (booted) {
|
||||
execSync(`npx cap run ios --target="${booted.udid}"`, { stdio: 'inherit' });
|
||||
log('✅ App launched');
|
||||
} else {
|
||||
log('⚠️ No booted simulator found');
|
||||
}
|
||||
} else {
|
||||
log('⚠️ Deeplink tests require the app to be running');
|
||||
log('⚠️ Please launch the app manually and restart the tests');
|
||||
rl.close();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
log('✅ App is running in simulator');
|
||||
}
|
||||
({ testEnv, contacts } = validateTestData(log));
|
||||
} catch (error) {
|
||||
log(`⚠️ Unable to check if app is running: ${error.message}`);
|
||||
log('⚠️ Proceeding with deeplink tests, but they may fail if app is not running');
|
||||
log('❌ Cannot proceed with tests due to invalid test data');
|
||||
log(`Error: ${error.message}`);
|
||||
log('Please ensure test data is properly generated before running tests');
|
||||
process.exit(1); // Exit with error code
|
||||
}
|
||||
|
||||
// Now we can safely create the deeplink tests knowing we have valid data
|
||||
const deeplinkTests = [
|
||||
{
|
||||
url: `timesafari://claim/${testEnv.CLAIM_ID}`,
|
||||
description: 'Claim view'
|
||||
},
|
||||
{
|
||||
url: `timesafari://claim-cert/${testEnv.CERT_ID || testEnv.CLAIM_ID}`,
|
||||
description: 'Claim certificate view'
|
||||
},
|
||||
{
|
||||
url: `timesafari://claim-add-raw/${testEnv.RAW_CLAIM_ID || testEnv.CLAIM_ID}`,
|
||||
description: 'Raw claim addition'
|
||||
},
|
||||
{
|
||||
url: 'timesafari://did/test',
|
||||
description: 'DID view with test identifier'
|
||||
},
|
||||
{
|
||||
url: `timesafari://did/${testEnv.CONTACT1_DID}`,
|
||||
description: 'DID view with contact DID'
|
||||
},
|
||||
{
|
||||
url: (() => {
|
||||
if (!testEnv?.CONTACT1_DID) {
|
||||
throw new Error('Cannot construct contact-edit URL: CONTACT1_DID is missing');
|
||||
}
|
||||
const url = `timesafari://contact-edit/${testEnv.CONTACT1_DID}`;
|
||||
log('Created contact-edit URL:', url);
|
||||
return url;
|
||||
})(),
|
||||
description: 'Contact editing'
|
||||
},
|
||||
{
|
||||
url: `timesafari://contacts/import?contacts=${encodeURIComponent(JSON.stringify(contacts))}`,
|
||||
description: 'Contacts import'
|
||||
}
|
||||
];
|
||||
|
||||
// Log the final test configuration
|
||||
log('\n5. Final Test Configuration:');
|
||||
deeplinkTests.forEach((test, i) => {
|
||||
log(`\nTest ${i + 1}:`);
|
||||
log(`Description: ${test.description}`);
|
||||
log(`URL: ${test.url}`);
|
||||
});
|
||||
|
||||
// Show instructions for iOS security dialogs
|
||||
log('\n📱 IMPORTANT: iOS Security Dialog Instructions:');
|
||||
log('1. Each deeplink test will trigger a security confirmation dialog');
|
||||
@@ -627,110 +682,41 @@ const runDeeplinkTests = async (log) => {
|
||||
await question('Press Enter when the app is visible and in the foreground...');
|
||||
|
||||
try {
|
||||
// Load test data
|
||||
log('📂 Loading test data from .generated directory');
|
||||
let testEnv, claimDetails, contacts;
|
||||
|
||||
try {
|
||||
const testEnvContent = readFileSync('.generated/test-env.json', 'utf8');
|
||||
testEnv = JSON.parse(testEnvContent);
|
||||
log('✅ Loaded test-env.json');
|
||||
} catch (error) {
|
||||
log(`⚠️ Failed to load test-env.json: ${error.message}`);
|
||||
rl.close();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const claimDetailsContent = readFileSync('.generated/claim_details.json', 'utf8');
|
||||
claimDetails = JSON.parse(claimDetailsContent);
|
||||
log('✅ Loaded claim_details.json');
|
||||
} catch (error) {
|
||||
log(`⚠️ Failed to load claim_details.json: ${error.message}`);
|
||||
rl.close();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const contactsContent = readFileSync('.generated/contacts.json', 'utf8');
|
||||
contacts = JSON.parse(contactsContent);
|
||||
log('✅ Loaded contacts.json');
|
||||
} catch (error) {
|
||||
log(`⚠️ Failed to load contacts.json: ${error.message}`);
|
||||
rl.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the app URL scheme is registered in the simulator
|
||||
log('🔍 Checking if URL scheme is registered in simulator...');
|
||||
try {
|
||||
// Attempt to open a simple URL with the scheme
|
||||
log('⚠️ A security dialog will appear - Click "Open" to continue');
|
||||
execSync(`xcrun simctl openurl booted "timesafari://test"`, { stdio: 'pipe' });
|
||||
log('✅ URL scheme is registered and working');
|
||||
} catch (error) {
|
||||
const errorMessage = error.message || '';
|
||||
|
||||
// Check for the specific error code that indicates an unregistered URL scheme
|
||||
if (errorMessage.includes('OSStatus error -10814') || errorMessage.includes('NSOSStatusErrorDomain, code=-10814')) {
|
||||
log('⚠️ URL scheme "timesafari://" is not registered in the app or app is not running');
|
||||
log('⚠️ The scheme was added to Info.plist but the app may need to be rebuilt');
|
||||
log('⚠️ Trying to continue with tests, but they may fail');
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for user confirmation before proceeding
|
||||
await question('Press Enter to continue with the tests...');
|
||||
|
||||
// Test URLs
|
||||
const deeplinkTests = [
|
||||
{
|
||||
url: `timesafari://claim/${claimDetails.claim_id}`,
|
||||
description: 'Claim view'
|
||||
},
|
||||
{
|
||||
url: `timesafari://claim-cert/${claimDetails.claim_id}`,
|
||||
description: 'Claim certificate view'
|
||||
},
|
||||
{
|
||||
url: `timesafari://claim-add-raw/${claimDetails.claim_id}`,
|
||||
description: 'Raw claim addition'
|
||||
},
|
||||
{
|
||||
url: 'timesafari://did/test',
|
||||
description: 'DID view with test identifier'
|
||||
},
|
||||
{
|
||||
url: `timesafari://did/${testEnv.CONTACT1_DID}`,
|
||||
description: 'DID view with contact DID'
|
||||
},
|
||||
{
|
||||
url: `timesafari://contact-edit/${testEnv.CONTACT1_DID}`,
|
||||
description: 'Contact editing'
|
||||
},
|
||||
{
|
||||
url: `timesafari://contacts/import?contacts=${encodeURIComponent(JSON.stringify(contacts))}`,
|
||||
description: 'Contacts import'
|
||||
}
|
||||
];
|
||||
|
||||
// Execute each test
|
||||
let testsCompleted = 0;
|
||||
let testsSkipped = 0;
|
||||
|
||||
for (const test of deeplinkTests) {
|
||||
// Show upcoming test info before execution
|
||||
log('\n📱 NEXT TEST:');
|
||||
log('------------------------');
|
||||
log(`Description: ${test.description}`);
|
||||
log(`URL to test: ${test.url}`);
|
||||
log('------------------------');
|
||||
|
||||
// Clear prompt for user action
|
||||
await question('\n⏎ Press Enter to execute this test (or Ctrl+C to quit)...');
|
||||
|
||||
try {
|
||||
log(`\n🔗 Testing deeplink: ${test.description}`);
|
||||
log(`URL: ${test.url}`);
|
||||
log('🚀 Executing deeplink test...');
|
||||
log('⚠️ iOS SECURITY DIALOG WILL APPEAR - Click "Open" to continue');
|
||||
|
||||
execSync(`xcrun simctl openurl booted "${test.url}"`, { stdio: 'pipe' });
|
||||
log(`✅ Successfully executed: ${test.description}`);
|
||||
testsCompleted++;
|
||||
|
||||
// Wait for user to press Enter before continuing to next test
|
||||
// Show progress
|
||||
log(`\n📊 Progress: ${testsCompleted}/${deeplinkTests.length} tests completed`);
|
||||
|
||||
// If there are more tests, show the next one
|
||||
if (testsCompleted < deeplinkTests.length) {
|
||||
await question('Press Enter to continue to the next test...');
|
||||
const nextTest = deeplinkTests[testsCompleted];
|
||||
log('\n⏭️ NEXT UP:');
|
||||
log('------------------------');
|
||||
log(`Next test will be: ${nextTest.description}`);
|
||||
log(`URL: ${nextTest.url}`);
|
||||
log('------------------------');
|
||||
await question('\n⏎ Press Enter when ready for the next test...');
|
||||
}
|
||||
} catch (deeplinkError) {
|
||||
const errorMessage = deeplinkError.message || '';
|
||||
@@ -745,14 +731,22 @@ const runDeeplinkTests = async (log) => {
|
||||
}
|
||||
log('⚠️ Continuing with next test...');
|
||||
|
||||
// Wait for user to press Enter before continuing to next test
|
||||
// Show next test info after error handling
|
||||
if (testsCompleted + testsSkipped < deeplinkTests.length) {
|
||||
await question('Press Enter to continue to the next test...');
|
||||
const nextTest = deeplinkTests[testsCompleted + testsSkipped];
|
||||
log('\n⏭️ NEXT UP:');
|
||||
log('------------------------');
|
||||
log(`Next test will be: ${nextTest.description}`);
|
||||
log(`URL: ${nextTest.url}`);
|
||||
log('------------------------');
|
||||
await question('\n⏎ Press Enter when ready for the next test...');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log(`✅ Deeplink tests completed: ${testsCompleted} successful, ${testsSkipped} skipped`);
|
||||
log('\n🎉 All deeplink tests completed!');
|
||||
log(`✅ Successful: ${testsCompleted}`);
|
||||
log(`⚠️ Skipped: ${testsSkipped}`);
|
||||
|
||||
if (testsSkipped > 0) {
|
||||
log('\n📝 Note about skipped tests:');
|
||||
@@ -762,15 +756,9 @@ const runDeeplinkTests = async (log) => {
|
||||
log('4. iOS security dialogs must be manually approved for each deeplink test');
|
||||
log('5. If these conditions are met and tests still fail, check URL handling in the app code');
|
||||
}
|
||||
|
||||
// Close readline interface
|
||||
rl.close();
|
||||
} catch (error) {
|
||||
log(`❌ Deeplink tests setup failed: ${error.message}`);
|
||||
log('⚠️ Deeplink tests might be unavailable or test data is missing');
|
||||
// Close readline interface
|
||||
rl.close();
|
||||
// Don't rethrow the error to prevent halting the process
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user