or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

app-snapshots.mdbuild-management.mdconfiguration.mdcore-operations.mdimage-uploads.mdindex.mdprogrammatic-api.mdstatic-snapshots.md

app-snapshots.mddocs/

0

# App Snapshots

1

2

Specialized commands for visual testing of native mobile applications with Percy's app testing platform. These commands provide Percy's visual testing capabilities for iOS and Android applications.

3

4

## Capabilities

5

6

### Percy App Exec

7

8

Execute command with Percy environment configured for native app visual testing. Similar to `percy exec` but optimized for mobile app testing workflows.

9

10

```bash { .api }

11

/**

12

* Execute command with Percy for native apps

13

* Starts Percy in app mode, runs command, then stops Percy

14

* Optimized for mobile app testing with native SDKs

15

*

16

* Usage: percy app exec -- <command>

17

*

18

* Arguments:

19

* command Command to execute (required, after --)

20

*

21

* Configuration:

22

* projectType: 'app' Native app project type

23

* server: true Percy server enabled

24

* skipDiscovery: true Asset discovery disabled (not needed for apps)

25

*

26

* Environment variables set:

27

* PERCY_SERVER_ADDRESS Local Percy server URL

28

* PERCY_BUILD_ID Current build identifier

29

* PERCY_BUILD_URL Percy dashboard URL for build

30

* PERCY_LOGLEVEL Current logging level

31

*/

32

percy app exec -- <command>

33

```

34

35

**Usage Examples:**

36

37

```bash

38

# iOS testing with XCTest

39

percy app exec -- xcodebuild test -project MyApp.xcodeproj -scheme MyAppTests

40

41

# Android testing with Espresso

42

percy app exec -- ./gradlew connectedAndroidTest

43

44

# React Native testing

45

percy app exec -- npm run test:e2e:ios

46

percy app exec -- npm run test:e2e:android

47

48

# Flutter testing

49

percy app exec -- flutter test integration_test/

50

```

51

52

### Percy App Start

53

54

Start Percy process specifically configured for native app testing. Creates a build and starts the server in app mode.

55

56

```bash { .api }

57

/**

58

* Start Percy process for native applications

59

* Initializes Percy server in app mode for mobile testing

60

* Must be paired with 'percy app stop' to finalize build

61

*

62

* Usage: percy app start

63

*

64

* Configuration:

65

* projectType: 'app' Native app project type

66

* server: true Percy server enabled

67

* skipDiscovery: true Asset discovery disabled

68

*/

69

percy app start

70

```

71

72

**Usage Examples:**

73

74

```bash

75

# Start Percy for app testing

76

percy app start

77

78

# Run your app tests (Percy server available for native SDKs)

79

xcodebuild test -project MyApp.xcodeproj -scheme MyAppTests

80

81

# Stop Percy when done

82

percy app stop

83

```

84

85

### Percy App Stop

86

87

Stop the Percy app process and finalize the build. Uploads any remaining snapshots and marks the build as complete.

88

89

```bash { .api }

90

/**

91

* Stop Percy app process and finalize build

92

* Uploads pending snapshots and marks build as complete

93

* Should be called after 'percy app start' and test execution

94

*

95

* Usage: percy app stop

96

*/

97

percy app stop

98

```

99

100

**Usage Examples:**

101

102

```bash

103

# Stop Percy app process

104

percy app stop

105

106

# Use in scripts

107

percy app start

108

./run-app-tests.sh

109

percy app stop

110

```

111

112

### Percy App Ping

113

114

Check if Percy app process is running and responsive. Useful for debugging and health checks in app testing environments.

115

116

```bash { .api }

117

/**

118

* Check if Percy app process is running

119

* Tests connectivity to local Percy server in app mode

120

*

121

* Usage: percy app ping

122

*

123

* Exit codes:

124

* 0 - Percy app is running and responsive

125

* 1 - Percy app is not running or not responsive

126

*/

127

percy app ping

128

```

129

130

**Usage Examples:**

131

132

```bash

133

# Check if Percy app is running

134

percy app ping

135

echo $? # 0 if running, 1 if not

136

137

# Use in conditional scripts

138

if percy app ping; then

139

echo "Percy app is running"

140

else

141

echo "Percy app is not running"

142

percy app start

143

fi

144

```

145

146

## Native SDK Integration

147

148

### iOS Integration (Swift/Objective-C)

149

150

Percy app commands work with the Percy iOS SDK to capture screenshots during XCTest execution:

151

152

```swift

153

// In your XCTest files

154

import Percy

155

156

class MyAppUITests: XCTestCase {

157

func testHomeScreen() {

158

let app = XCUIApplication()

159

app.launch()

160

161

// Navigate to home screen

162

app.buttons["Home"].tap()

163

164

// Capture Percy snapshot

165

Percy.screenshot(name: "Home Screen")

166

}

167

168

func testProfileScreen() {

169

let app = XCUIApplication()

170

app.launch()

171

172

// Navigate to profile

173

app.tabBars.buttons["Profile"].tap()

174

175

// Capture with options

176

Percy.screenshot(name: "Profile Screen", options: [

177

"widths": [375, 414]

178

])

179

}

180

}

181

```

182

183

```bash

184

# Run tests with Percy

185

percy app exec -- xcodebuild test \

186

-project MyApp.xcodeproj \

187

-scheme MyAppUITests \

188

-destination 'platform=iOS Simulator,name=iPhone 13'

189

```

190

191

### Android Integration (Java/Kotlin)

192

193

Integration with Android Espresso tests using Percy Android SDK:

194

195

```kotlin

196

// In your Android test files

197

import io.percy.espresso.Percy

198

199

@RunWith(AndroidJUnit4::class)

200

class MainActivityTest {

201

202

@get:Rule

203

val activityRule = ActivityTestRule(MainActivity::class.java)

204

205

@Test

206

fun testHomeScreen() {

207

// Navigate to home screen

208

onView(withId(R.id.home_button)).perform(click())

209

210

// Capture Percy snapshot

211

Percy.screenshot(activityRule.activity, "Home Screen")

212

}

213

214

@Test

215

fun testProfileScreen() {

216

// Navigate to profile

217

onView(withId(R.id.profile_tab)).perform(click())

218

219

// Capture with options

220

val options = mutableMapOf<String, Any>()

221

options["widths"] = listOf(375, 414)

222

Percy.screenshot(activityRule.activity, "Profile Screen", options)

223

}

224

}

225

```

226

227

```bash

228

# Run Android tests with Percy

229

percy app exec -- ./gradlew connectedAndroidTest

230

```

231

232

### React Native Integration

233

234

Integration with React Native testing frameworks:

235

236

```javascript

237

// detox-tests.js (Detox example)

238

import { device, element, by } from 'detox';

239

import { percyScreenshot } from '@percy/detox';

240

241

describe('React Native App', () => {

242

beforeAll(async () => {

243

await device.launchApp();

244

});

245

246

it('should display home screen correctly', async () => {

247

await element(by.id('home-screen')).waitToBeVisible();

248

249

// Capture Percy snapshot

250

await percyScreenshot(device, 'Home Screen');

251

});

252

253

it('should display profile screen correctly', async () => {

254

await element(by.id('profile-tab')).tap();

255

await element(by.id('profile-screen')).waitToBeVisible();

256

257

// Capture with options

258

await percyScreenshot(device, 'Profile Screen', {

259

widths: [375, 414]

260

});

261

});

262

});

263

```

264

265

```bash

266

# Run Detox tests with Percy

267

percy app exec -- detox test --configuration ios.sim.debug

268

```

269

270

### Flutter Integration

271

272

Integration with Flutter integration tests:

273

274

```dart

275

// integration_test/app_test.dart

276

import 'package:flutter/services.dart';

277

import 'package:flutter_test/flutter_test.dart';

278

import 'package:integration_test/integration_test.dart';

279

import 'package:percy_flutter/percy_flutter.dart';

280

import 'package:myapp/main.dart' as app;

281

282

void main() {

283

IntegrationTestWidgetsFlutterBinding.ensureInitialized();

284

285

group('App Screenshots', () {

286

testWidgets('Home screen', (WidgetTester tester) async {

287

app.main();

288

await tester.pumpAndSettle();

289

290

// Navigate to home

291

await tester.tap(find.text('Home'));

292

await tester.pumpAndSettle();

293

294

// Capture Percy snapshot

295

await PercyFlutter.screenshot('Home Screen');

296

});

297

298

testWidgets('Profile screen', (WidgetTester tester) async {

299

app.main();

300

await tester.pumpAndSettle();

301

302

// Navigate to profile

303

await tester.tap(find.text('Profile'));

304

await tester.pumpAndSettle();

305

306

// Capture with options

307

await PercyFlutter.screenshot('Profile Screen',

308

widths: [375, 414]);

309

});

310

});

311

}

312

```

313

314

```bash

315

# Run Flutter integration tests with Percy

316

percy app exec -- flutter test integration_test/

317

```

318

319

## Configuration

320

321

### App-Specific Settings

322

323

Percy app commands use specialized configuration optimized for mobile testing:

324

325

```yaml

326

# .percy.yml for app projects

327

version: 2

328

app:

329

projectType: 'app'

330

server: true

331

skipDiscovery: true

332

333

snapshot:

334

widths: [375, 414, 768] # Common mobile widths

335

minHeight: 667

336

```

337

338

### Environment Variables

339

340

App commands set specific environment variables:

341

342

```bash { .api }

343

# Set by Percy app commands

344

PERCY_SERVER_ADDRESS # Local Percy server URL

345

PERCY_BUILD_ID # Current build identifier

346

PERCY_BUILD_URL # Percy dashboard URL for build

347

PERCY_LOGLEVEL # Current logging level

348

349

# App-specific configuration

350

PERCY_PROJECT_TYPE=app # Identifies as app project

351

PERCY_SKIP_DISCOVERY=true # Disables web asset discovery

352

```

353

354

## Device and Simulator Support

355

356

### iOS Simulators

357

358

```bash

359

# Test on specific iOS simulator

360

percy app exec -- xcodebuild test \

361

-project MyApp.xcodeproj \

362

-scheme MyAppUITests \

363

-destination 'platform=iOS Simulator,name=iPhone 13 Pro'

364

365

# Test on multiple simulators

366

percy app exec -- xcodebuild test \

367

-project MyApp.xcodeproj \

368

-scheme MyAppUITests \

369

-destination 'platform=iOS Simulator,name=iPhone 13' \

370

-destination 'platform=iOS Simulator,name=iPad Air'

371

```

372

373

### Android Emulators

374

375

```bash

376

# Test on specific Android emulator

377

percy app exec -- ./gradlew connectedAndroidTest

378

379

# Test with specific device configuration

380

percy app exec -- ./gradlew connectedAndroidTest \

381

-Pandroid.testInstrumentationRunnerArguments.size=medium

382

```

383

384

### Physical Devices

385

386

```bash

387

# iOS physical device testing

388

percy app exec -- xcodebuild test \

389

-project MyApp.xcodeproj \

390

-scheme MyAppUITests \

391

-destination 'platform=iOS,name=My iPhone'

392

393

# Android physical device testing

394

percy app exec -- ./gradlew connectedAndroidTest \

395

-Pandroid.testInstrumentationRunnerArguments.device=physical

396

```

397

398

## CI/CD Integration

399

400

### GitHub Actions

401

402

```yaml

403

# .github/workflows/app-visual-tests.yml

404

name: App Visual Tests

405

406

on: [push, pull_request]

407

408

jobs:

409

ios-tests:

410

runs-on: macos-latest

411

steps:

412

- uses: actions/checkout@v2

413

414

- name: Setup iOS Simulator

415

run: |

416

xcrun simctl boot "iPhone 13"

417

418

- name: Run Percy iOS tests

419

env:

420

PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

421

run: |

422

percy app exec -- xcodebuild test \

423

-project MyApp.xcodeproj \

424

-scheme MyAppUITests \

425

-destination 'platform=iOS Simulator,name=iPhone 13'

426

427

android-tests:

428

runs-on: ubuntu-latest

429

steps:

430

- uses: actions/checkout@v2

431

432

- name: Setup Android Emulator

433

uses: reactivecircus/android-emulator-runner@v2

434

with:

435

api-level: 29

436

script: |

437

export PERCY_TOKEN=${{ secrets.PERCY_TOKEN }}

438

percy app exec -- ./gradlew connectedAndroidTest

439

```

440

441

### Jenkins Pipeline

442

443

```groovy

444

pipeline {

445

agent any

446

447

environment {

448

PERCY_TOKEN = credentials('percy-token')

449

}

450

451

stages {

452

stage('iOS Tests') {

453

steps {

454

sh '''

455

percy app exec -- xcodebuild test \

456

-project MyApp.xcodeproj \

457

-scheme MyAppUITests \

458

-destination 'platform=iOS Simulator,name=iPhone 13'

459

'''

460

}

461

}

462

463

stage('Android Tests') {

464

steps {

465

sh '''

466

percy app exec -- ./gradlew connectedAndroidTest

467

'''

468

}

469

}

470

}

471

}

472

```

473

474

## Error Handling

475

476

### Common Issues

477

478

```bash

479

# Handle simulator/emulator startup issues

480

if ! xcrun simctl list | grep -q "iPhone 13 (Booted)"; then

481

echo "Starting iOS Simulator..."

482

xcrun simctl boot "iPhone 13"

483

sleep 10

484

fi

485

486

percy app exec -- xcodebuild test -project MyApp.xcodeproj -scheme MyAppUITests

487

488

# Handle Android emulator issues

489

adb wait-for-device

490

adb shell input keyevent 82 # Unlock device

491

492

percy app exec -- ./gradlew connectedAndroidTest

493

```

494

495

### Debugging

496

497

```bash

498

# Enable debug logging

499

PERCY_LOGLEVEL=debug percy app exec -- npm run test:e2e

500

501

# Check Percy server status

502

percy app ping || {

503

echo "Percy app server not responding"

504

percy app stop

505

percy app start

506

}

507

508

# Verify SDK integration

509

# Check that native SDK calls are reaching Percy server

510

tail -f ~/.percy/logs/percy.log

511

```

512

513

## Best Practices

514

515

### Test Organization

516

517

```bash

518

# Organize tests by feature

519

percy app exec -- xcodebuild test \

520

-project MyApp.xcodeproj \

521

-scheme AuthenticationTests

522

523

percy app exec -- xcodebuild test \

524

-project MyApp.xcodeproj \

525

-scheme NavigationTests

526

527

percy app exec -- xcodebuild test \

528

-project MyApp.xcodeproj \

529

-scheme ProfileTests

530

```

531

532

### Screenshot Naming

533

534

```swift

535

// Use descriptive, hierarchical names

536

Percy.screenshot(name: "Login - Empty Form")

537

Percy.screenshot(name: "Login - With Errors")

538

Percy.screenshot(name: "Login - Success")

539

540

Percy.screenshot(name: "Profile - View Mode")

541

Percy.screenshot(name: "Profile - Edit Mode")

542

Percy.screenshot(name: "Profile - Saving State")

543

```

544

545

### Performance Optimization

546

547

```bash

548

# Run tests in parallel where possible

549

percy app exec -- xcodebuild test \

550

-project MyApp.xcodeproj \

551

-scheme MyAppUITests \

552

-parallel-testing-enabled YES

553

554

# Use specific test classes to reduce runtime

555

percy app exec -- xcodebuild test \

556

-project MyApp.xcodeproj \

557

-scheme MyAppUITests \

558

-only-testing:MyAppUITests/LoginTests

559

```