|
13 | 13 | import java.nio.file.Files; |
14 | 14 | import java.nio.file.Path; |
15 | 15 | import java.nio.file.Paths; |
16 | | -import java.text.SimpleDateFormat; |
17 | 16 | import java.time.Duration; |
18 | 17 | import java.util.Base64; |
19 | 18 |
|
20 | 19 | public class IOSAppiumScreenRecorderForMac extends IOSAppiumScreenRecorder { |
21 | 20 |
|
22 | 21 | public IOSAppiumScreenRecorderForMac(DeviceDriver deviceDriver, DeviceInfo info, String recordDir) { |
23 | 22 | super(deviceDriver, info, recordDir); |
| 23 | + CLASS_LOGGER.info("🎬 IOSAppiumScreenRecorderForMac initialized. Record dir: {}", recordDir); |
24 | 24 | } |
25 | 25 |
|
26 | 26 | @Override |
27 | 27 | public void startRecord(int maxTimeInSecond) { |
| 28 | + if (!isDriverInitialized || iosDriver == null) { |
| 29 | + CLASS_LOGGER.error("❌ Cannot start recording - IOSDriver not initialized. Skipping video recording."); |
| 30 | + CLASS_LOGGER.error("💡 Ensure WDA (WebDriverAgent) is installed on the iOS device."); |
| 31 | + return; |
| 32 | + } |
| 33 | + |
28 | 34 | int timeout = maxTimeInSecond > 0 ? maxTimeInSecond : DEFAULT_TIMEOUT_IN_SECOND; |
| 35 | + CLASS_LOGGER.info("🎬 Starting iOS screen recording for device: {} (timeout: {}s)", |
| 36 | + deviceInfo.getSerialNum(), timeout); |
29 | 37 | try { |
30 | 38 | FlowUtil.retryAndSleepWhenFalse(3, 10, () -> { |
| 39 | + CLASS_LOGGER.info("📹 Calling iosDriver.startRecordingScreen() with 720p @ 30fps..."); |
31 | 40 | iosDriver.startRecordingScreen(new IOSStartScreenRecordingOptions() |
32 | 41 | .enableForcedRestart() |
33 | | - .withFps(24) |
| 42 | + .withFps(30) // 30 fps for smoother video |
34 | 43 | .withVideoType("h264") |
35 | | - .withVideoScale("720:360") |
| 44 | + .withVideoScale("1280:720") // 720p resolution (was 720:360) |
| 45 | + .withVideoQuality(IOSStartScreenRecordingOptions.VideoQuality.HIGH) |
36 | 46 | .withTimeLimit(Duration.ofSeconds(timeout))); |
37 | 47 | return true; |
38 | 48 | }); |
39 | 49 | isStarted = true; |
| 50 | + CLASS_LOGGER.info("✅ iOS screen recording started successfully for device: {}", deviceInfo.getSerialNum()); |
40 | 51 | } catch (Exception e) { |
41 | | - System.out.println("-------------------------------Fail to Start recording, Ignore it to unblocking the following tests----------------------------"); |
42 | | - e.printStackTrace(); |
43 | | - System.out.println("-------------------------------------------------------Ignore End--------------------------------------------------------------"); |
| 52 | + CLASS_LOGGER.error("❌ Failed to start iOS screen recording: {}", e.getMessage()); |
| 53 | + CLASS_LOGGER.error("💡 Possible causes: WDA not running, Appium session expired, or device disconnected."); |
| 54 | + CLASS_LOGGER.debug("Stack trace:", e); |
44 | 55 | } |
45 | 56 | } |
46 | 57 |
|
47 | 58 | @Override |
48 | 59 | public String finishRecording() { |
49 | 60 | if (!isStarted) { |
| 61 | + CLASS_LOGGER.warn("⚠️ finishRecording() called but recording was never started. Returning null."); |
| 62 | + return null; |
| 63 | + } |
| 64 | + |
| 65 | + if (iosDriver == null) { |
| 66 | + CLASS_LOGGER.error("❌ Cannot stop recording - IOSDriver is null."); |
| 67 | + isStarted = false; |
50 | 68 | return null; |
51 | 69 | } |
52 | | - SimpleDateFormat format = new SimpleDateFormat( |
53 | | - "yyyy-MM-dd-HH-mm-ss"); |
| 70 | + |
| 71 | + CLASS_LOGGER.info("⏹️ Stopping iOS screen recording for device: {}", deviceInfo.getSerialNum()); |
54 | 72 | String destPath = ""; |
55 | 73 | try { |
56 | 74 | // wait 5s to record more info after testing |
| 75 | + CLASS_LOGGER.info("⏳ Waiting 5s before stopping recording..."); |
57 | 76 | ThreadUtils.safeSleep(5000); |
| 77 | + |
| 78 | + CLASS_LOGGER.info("📹 Calling iosDriver.stopRecordingScreen()..."); |
58 | 79 | String base64String = iosDriver.stopRecordingScreen(); |
| 80 | + |
| 81 | + if (base64String == null || base64String.isEmpty()) { |
| 82 | + CLASS_LOGGER.error("❌ stopRecordingScreen() returned empty data."); |
| 83 | + isStarted = false; |
| 84 | + return null; |
| 85 | + } |
| 86 | + |
59 | 87 | byte[] data = Base64.getDecoder().decode(base64String); |
60 | 88 | destPath = new File(recordDir, Const.ScreenRecoderConfig.DEFAULT_FILE_NAME).getAbsolutePath(); |
61 | 89 | Path path = Paths.get(destPath); |
62 | 90 | Files.write(path, data); |
63 | 91 | isStarted = false; |
| 92 | + |
| 93 | + File videoFile = new File(destPath); |
| 94 | + if (videoFile.exists() && videoFile.length() > 0) { |
| 95 | + CLASS_LOGGER.info("✅ iOS screen recording saved successfully: {} ({}KB)", |
| 96 | + destPath, videoFile.length() / 1024); |
| 97 | + } else { |
| 98 | + CLASS_LOGGER.error("❌ Video file was not created or is empty: {}", destPath); |
| 99 | + return null; |
| 100 | + } |
64 | 101 | } catch (Throwable e) { |
65 | | - System.out.println("-------------------------------Fail to Stop recording, Ignore it to unblocking the following tests-----------------------------"); |
66 | | - e.printStackTrace(); |
67 | | - System.out.println("-------------------------------------------------------Ignore End--------------------------------------------------------------"); |
| 102 | + CLASS_LOGGER.error("❌ Failed to stop iOS screen recording: {}", e.getMessage()); |
| 103 | + CLASS_LOGGER.error("💡 Possible causes: Recording timeout exceeded, WDA crashed, or device disconnected."); |
| 104 | + CLASS_LOGGER.debug("Stack trace:", e); |
| 105 | + isStarted = false; |
68 | 106 | return null; |
69 | 107 | } |
70 | 108 | return destPath; |
|
0 commit comments