chore: update package.json for testing scripts and dependencies
- Added unit and end-to-end testing scripts to package.json. - Included detox for end-to-end testing and jest-circus for improved test execution. feat: add testID to LandingScreen logo for better testing - Added testID attribute to the logo image in LandingScreen for easier identification in tests. feat: create tokens.ts to re-export design tokens - Introduced tokens.ts to re-export shared design tokens from lightTheme for consistent imports.
This commit is contained in:
109
app/e2e/run-detox.js
Normal file
109
app/e2e/run-detox.js
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env node
|
||||
const { exec, spawn } = require('child_process');
|
||||
|
||||
const ROOT_DIR = __dirname + '/..';
|
||||
|
||||
function run(cmd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const p = exec(cmd, { cwd: ROOT_DIR, maxBuffer: 1024 * 1024 * 10 });
|
||||
p.stdout.pipe(process.stdout);
|
||||
p.stderr.pipe(process.stderr);
|
||||
p.on('close', code => (code === 0 ? resolve() : reject(new Error(cmd + ' exited with ' + code))));
|
||||
});
|
||||
}
|
||||
|
||||
function adbList() {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec('adb devices -l', (err, stdout) => {
|
||||
if (err) return reject(err);
|
||||
resolve(stdout);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Metro is already listening on port 8081.
|
||||
*/
|
||||
function isMetroRunning() {
|
||||
return new Promise(resolve => {
|
||||
exec('lsof -iTCP:8081 -sTCP:LISTEN -t', (err, stdout) => {
|
||||
resolve(!err && stdout.trim().length > 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Metro bundler in the background. Returns a cleanup function.
|
||||
*/
|
||||
function startMetro() {
|
||||
console.log('[run-detox] Starting Metro bundler on port 8081...');
|
||||
const metro = spawn('npx', ['react-native', 'start', '--port', '8081', '--reset-cache'], {
|
||||
cwd: ROOT_DIR,
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
detached: false,
|
||||
});
|
||||
metro.stdout.on('data', d => process.stdout.write('[metro] ' + d));
|
||||
metro.stderr.on('data', d => process.stderr.write('[metro] ' + d));
|
||||
metro.on('error', err => console.error('[run-detox] Metro error:', err.message));
|
||||
return metro;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until Metro is ready (listening on 8081), with a timeout.
|
||||
*/
|
||||
function waitForMetro(timeoutMs = 60000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const start = Date.now();
|
||||
const interval = setInterval(() => {
|
||||
exec('lsof -iTCP:8081 -sTCP:LISTEN -t', (err, stdout) => {
|
||||
if (!err && stdout.trim().length > 0) {
|
||||
clearInterval(interval);
|
||||
resolve();
|
||||
} else if (Date.now() - start > timeoutMs) {
|
||||
clearInterval(interval);
|
||||
reject(new Error('Timed out waiting for Metro to start on port 8081'));
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
let metroProcess = null;
|
||||
try {
|
||||
const out = await adbList();
|
||||
const lines = out.split('\n').slice(1).map(l => l.trim()).filter(Boolean);
|
||||
// filter out emulator entries (emulator-*) and look for 'device' state
|
||||
const attached = lines
|
||||
.map(l => l.split(/\s+/)[0])
|
||||
.filter(id => id && !id.startsWith('emulator-'));
|
||||
|
||||
const useConfig = attached.length > 0 ? 'android.attached+android.debug' : 'android.emu.debug+android.debug';
|
||||
console.log('\n[run-detox] Detected attached devices:', attached.join(', ') || '(none)');
|
||||
console.log('[run-detox] Using configuration:', useConfig, '\n');
|
||||
|
||||
// Ensure Metro is running (required for debug APK to load the JS bundle)
|
||||
const metroAlready = await isMetroRunning();
|
||||
if (metroAlready) {
|
||||
console.log('[run-detox] Metro is already running on port 8081.');
|
||||
} else {
|
||||
metroProcess = startMetro();
|
||||
console.log('[run-detox] Waiting for Metro to be ready (up to 60s)...');
|
||||
await waitForMetro(60000);
|
||||
console.log('[run-detox] Metro is ready.\n');
|
||||
}
|
||||
|
||||
console.log('Building...');
|
||||
await run(`npx detox build -c ${useConfig}`);
|
||||
console.log('Running tests...');
|
||||
await run(`npx detox test -c ${useConfig}`);
|
||||
} catch (err) {
|
||||
console.error('\n[run-detox] Error:', err.message || err);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
if (metroProcess) {
|
||||
console.log('\n[run-detox] Stopping Metro bundler...');
|
||||
metroProcess.kill('SIGTERM');
|
||||
}
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user