From 6c1c91365b01c92f2742a741d187fad404d3bd43 Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Wed, 21 Nov 2018 12:34:46 +0900 Subject: [PATCH 1/6] add tests for screen recording in functionality --- .../android/uiautomator2/device.rb | 2 +- lib/appium_lib_core/common/base/screenshot.rb | 2 +- lib/appium_lib_core/ios/xcuitest/device.rb | 24 ++++++++++----- .../ios/xcuitest/device/screen.rb | 5 +++- .../android/android/mjpeg_server_test.rb | 30 +++++++++++++++++++ test/functional/ios/ios/mjpeg_server_test.rb | 10 +++++++ test/unit/ios/device/mjsonwp/commands_test.rb | 10 +++---- test/unit/ios/device/w3c/commands_test.rb | 6 ++-- 8 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 test/functional/android/android/mjpeg_server_test.rb diff --git a/lib/appium_lib_core/android/uiautomator2/device.rb b/lib/appium_lib_core/android/uiautomator2/device.rb index e66420e8..188eccad 100644 --- a/lib/appium_lib_core/android/uiautomator2/device.rb +++ b/lib/appium_lib_core/android/uiautomator2/device.rb @@ -7,7 +7,7 @@ module Uiautomator2 module Device extend Forwardable - # @since 1.6.0 + # @since Appium 1.6.0 # @!method battery_info # # Get battery information. diff --git a/lib/appium_lib_core/common/base/screenshot.rb b/lib/appium_lib_core/common/base/screenshot.rb index 26e20dc6..6c570e6e 100644 --- a/lib/appium_lib_core/common/base/screenshot.rb +++ b/lib/appium_lib_core/common/base/screenshot.rb @@ -78,7 +78,7 @@ def element_screenshot_as(element, format) end end - # @since 1.3.4 + # @since Appium 1.3.4 # @!method save_viewport_screenshot # Save screenshot except for status bar while `@driver.save_screenshot` save entire screen. # diff --git a/lib/appium_lib_core/ios/xcuitest/device.rb b/lib/appium_lib_core/ios/xcuitest/device.rb index fcb9724b..649bb328 100644 --- a/lib/appium_lib_core/ios/xcuitest/device.rb +++ b/lib/appium_lib_core/ios/xcuitest/device.rb @@ -36,7 +36,12 @@ module Device # @driver.background_app(-1) #=> the app never come back. https://github.com/appium/appium/issues/7741 # - # @!method start_recording_screen(remote_path: nil, user: nil, pass: nil, method: nil, force_restart: nil, video_type: 'mp4', time_limit: '180', video_quality: 'medium') + # @since Appium 1.9.1 + # @!method start_recording_screen(remote_path: nil, user: nil, pass: nil, method: nil, force_restart: nil, video_type: 'mjpeg', time_limit: '180', video_quality: 'medium', video_scale: '320:240') + # + # Record the display of devices running iOS Simulator since Xcode 9 or real devices since iOS 11 + # (ffmpeg utility is required: 'brew install ffmpeg'). + # # @param [String] remote_path: The path to the remote location, where the resulting video should be uploaded. # The following protocols are supported: http/https, ftp. # Null or empty string value (the default setting) means the content of resulting @@ -51,21 +56,24 @@ module Device # @param [Boolean] force_restart: Whether to try to catch and upload/return the currently running screen recording # (`false`, the default setting on server) or ignore the result of it # and start a new recording immediately (`true`). - # @param [String] video_type: The format of the screen capture to be recorded. - # Available formats: "h264", "mp4" or "fmp4". Default is "mp4". - # Only works for Simulator. + # @param [String] video_type: The video codec type used for encoding of the be recorded screen capture. + # Execute `ffmpeg -codecs` in the terminal to see the list of supported video codecs. + # 'mjpeg' by default. # @param [String] time_limit: Recording time. 180 seconds is by default. # @param [String] video_quality: The video encoding quality (low, medium, high, photo - defaults to medium). # @param [String] video_fps: The Frames Per Second rate of the recorded video. Change this value if the resulting video # is too slow or too fast. Defaults to 10. This can decrease the resulting file size. + # @param [String] video_scale: The scaling value to apply. Read https://trac.ffmpeg.org/wiki/Scaling for possible values. + # No scale is applied by default. # # @example # # @driver.start_recording_screen - # @driver.start_recording_screen video_type: 'h264', time_limit: '260' + # @driver.start_recording_screen video_type: 'mjpeg', time_limit: '260' + # @driver.start_recording_screen video_type: 'mpeg4', time_limit: '260' # mpeg4 is available via `ffmpeg -codecs` # - # @since 1.3.4 + # @since Appium 1.3.4 # @!method start_performance_record(timeout: 300000, profile_name: 'Activity Monitor') # # This is a blocking application. @@ -88,7 +96,7 @@ module Device # @driver.start_performance_record(timeout: 300000, profile_name: 'Activity Monitor') # - # @since 1.3.4 + # @since Appium 1.3.4 # @!method get_performance_record(save_file_path: './performance', profile_name: 'Activity Monitor', remote_path: nil, user: nil, pass: nil, method: 'PUT') # # This is a blocking application. @@ -115,7 +123,7 @@ module Device # @driver.get_performance_record # @driver.get_performance_record(save_file_path: './performance', profile_name: 'Activity Monitor') - # @since 1.6.0 + # @since Appium 1.6.0 # @!method battery_info # # Get battery information. diff --git a/lib/appium_lib_core/ios/xcuitest/device/screen.rb b/lib/appium_lib_core/ios/xcuitest/device/screen.rb index 0d0b93b5..05006ebe 100644 --- a/lib/appium_lib_core/ios/xcuitest/device/screen.rb +++ b/lib/appium_lib_core/ios/xcuitest/device/screen.rb @@ -8,7 +8,8 @@ def self.add_methods ::Appium::Core::Device.add_endpoint_method(:start_recording_screen) do # rubocop:disable Metrics/ParameterLists def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: nil, force_restart: nil, - video_type: 'mp4', time_limit: '180', video_quality: 'medium', video_fps: nil) + video_type: 'mjpeg', time_limit: '180', video_quality: 'medium', + video_fps: nil, video_scale: nil ) option = ::Appium::Core::Base::Device::ScreenRecord.new( remote_path: remote_path, user: user, pass: pass, method: method, force_restart: force_restart ).upload_option @@ -16,7 +17,9 @@ def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: nil, option[:videoType] = video_type option[:timeLimit] = time_limit option[:videoQuality] = video_quality + option[:videoFps] = video_fps unless video_fps.nil? + option[:videoScale] = video_scale unless video_scale.nil? execute(:start_recording_screen, {}, { options: option }) end diff --git a/test/functional/android/android/mjpeg_server_test.rb b/test/functional/android/android/mjpeg_server_test.rb new file mode 100644 index 00000000..776f3ec2 --- /dev/null +++ b/test/functional/android/android/mjpeg_server_test.rb @@ -0,0 +1,30 @@ +require 'test_helper' + +# $ rake test:func:ios TEST=test/functional/android/android/mjpeg_server_test.rb +# rubocop:disable Style/ClassVars +class AppiumLibCoreTest + module Android + class MjpegServerTest < AppiumLibCoreTest::Function::TestCase + def setup + @@core ||= ::Appium::Core.for(Caps.android) + @@driver ||= @@core.start_driver + end + + def teardown + save_reports(@@driver) + end + + def test_start_recording_screen + to_path = 'recorded_file_android.mp4' + File.delete to_path if File.exist? to_path + + @@driver.start_recording_screen time_limit: '2' + @driver.find_element(:accessibility_id, 'App').click + sleep 2 # second + @@driver.stop_and_save_recording_screen to_path + assert File.exist? to_path + end + end + end +end +# rubocop:enable Style/ClassVars diff --git a/test/functional/ios/ios/mjpeg_server_test.rb b/test/functional/ios/ios/mjpeg_server_test.rb index 0d625e54..66f680c3 100644 --- a/test/functional/ios/ios/mjpeg_server_test.rb +++ b/test/functional/ios/ios/mjpeg_server_test.rb @@ -23,6 +23,16 @@ def test_config @@driver.update_settings({ mjpegServerScreenshotQuality: -10, mjpegServerFramerate: 60 }) @@driver.update_settings({ mjpegServerScreenshotQuality: 100, mjpegServerFramerate: 60 }) end + + def test_start_recording_screen + to_path = 'recorded_file_ios.mp4' + File.delete to_path if File.exist? to_path + + @@driver.start_recording_screen time_limit: '2' + sleep 5 # second + @@driver.stop_and_save_recording_screen to_path + assert File.exist? to_path + end end end end diff --git a/test/unit/ios/device/mjsonwp/commands_test.rb b/test/unit/ios/device/mjsonwp/commands_test.rb index 45bbfe51..b56282e5 100644 --- a/test/unit/ios/device/mjsonwp/commands_test.rb +++ b/test/unit/ios/device/mjsonwp/commands_test.rb @@ -36,7 +36,7 @@ def test_toggle_touch_id_enrollment def test_start_recording_screen stub_request(:post, "#{SESSION}/appium/start_recording_screen") - .with(body: { options: { videoType: 'mp4', timeLimit: '180', videoQuality: 'medium' } }.to_json) + .with(body: { options: { videoType: 'mjpeg', timeLimit: '180', videoQuality: 'medium' } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) @driver.start_recording_screen @@ -46,10 +46,10 @@ def test_start_recording_screen def test_start_recording_screen_custom stub_request(:post, "#{SESSION}/appium/start_recording_screen") - .with(body: { options: { videoType: 'h265', timeLimit: '60', videoQuality: 'medium' } }.to_json) + .with(body: { options: { videoType: 'hevc', timeLimit: '60', videoQuality: 'medium', videoScale: '320:240' } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) - @driver.start_recording_screen video_type: 'h265', time_limit: '60' + @driver.start_recording_screen video_type: 'hevc', time_limit: '60', video_scale: '320:240' assert_requested(:post, "#{SESSION}/appium/start_recording_screen", times: 1) end @@ -57,10 +57,10 @@ def test_start_recording_screen_custom def test_start_recording_screen_custom_force stub_request(:post, "#{SESSION}/appium/start_recording_screen") .with(body: - { options: { forceRestart: true, videoType: 'h265', timeLimit: '60', videoQuality: 'medium' } }.to_json) + { options: { forceRestart: true, videoType: 'hevc', timeLimit: '60', videoQuality: 'medium' } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) - @driver.start_recording_screen video_type: 'h265', time_limit: '60', force_restart: true + @driver.start_recording_screen video_type: 'hevc', time_limit: '60', force_restart: true assert_requested(:post, "#{SESSION}/appium/start_recording_screen", times: 1) end diff --git a/test/unit/ios/device/w3c/commands_test.rb b/test/unit/ios/device/w3c/commands_test.rb index 7666cb07..2a5debcd 100644 --- a/test/unit/ios/device/w3c/commands_test.rb +++ b/test/unit/ios/device/w3c/commands_test.rb @@ -34,7 +34,7 @@ def test_toggle_touch_id_enrollment def test_start_recording_screen stub_request(:post, "#{SESSION}/appium/start_recording_screen") - .with(body: { options: { videoType: 'mp4', timeLimit: '180', videoQuality: 'medium' } }.to_json) + .with(body: { options: { videoType: 'mjpeg', timeLimit: '180', videoQuality: 'medium' } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) @driver.start_recording_screen @@ -44,10 +44,10 @@ def test_start_recording_screen def test_start_recording_screen_custom stub_request(:post, "#{SESSION}/appium/start_recording_screen") - .with(body: { options: { videoType: 'h265', timeLimit: '60', videoQuality: 'medium', videoFps: '50' } }.to_json) + .with(body: { options: { videoType: 'hevc', timeLimit: '60', videoQuality: 'medium', videoFps: '50', videoScale: '320:240' } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) - @driver.start_recording_screen video_type: 'h265', time_limit: '60', video_fps: '50' + @driver.start_recording_screen video_type: 'hevc', time_limit: '60', video_fps: '50', video_scale: '320:240' assert_requested(:post, "#{SESSION}/appium/start_recording_screen", times: 1) end From 9f42cf6fd9c964e84f9bc0295f59454ab3b330a2 Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Wed, 21 Nov 2018 13:24:28 +0900 Subject: [PATCH 2/6] tweak test cases --- lib/appium_lib_core/common/base/driver.rb | 6 ++++++ lib/appium_lib_core/ios/xcuitest/device.rb | 2 +- test/functional/ios/ios/mjpeg_server_test.rb | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/appium_lib_core/common/base/driver.rb b/lib/appium_lib_core/common/base/driver.rb index 50a46e0f..0ee0ddc2 100644 --- a/lib/appium_lib_core/common/base/driver.rb +++ b/lib/appium_lib_core/common/base/driver.rb @@ -583,6 +583,12 @@ def stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT') # # @example # + # # iOS + # @driver.start_recording_screen video_type: 'libx264' + # @driver.stop_and_save_recording_screen 'example.mp4' # Video type `libx264` can be play as `.mp4` video + # + # # Android + # @driver.start_recording_screen # @driver.stop_and_save_recording_screen 'example.mp4' # def stop_and_save_recording_screen(file_path) diff --git a/lib/appium_lib_core/ios/xcuitest/device.rb b/lib/appium_lib_core/ios/xcuitest/device.rb index 649bb328..c8b08c26 100644 --- a/lib/appium_lib_core/ios/xcuitest/device.rb +++ b/lib/appium_lib_core/ios/xcuitest/device.rb @@ -70,7 +70,7 @@ module Device # # @driver.start_recording_screen # @driver.start_recording_screen video_type: 'mjpeg', time_limit: '260' - # @driver.start_recording_screen video_type: 'mpeg4', time_limit: '260' # mpeg4 is available via `ffmpeg -codecs` + # @driver.start_recording_screen video_type: 'libx264', time_limit: '260' # Can get `.mp4` video # # @since Appium 1.3.4 diff --git a/test/functional/ios/ios/mjpeg_server_test.rb b/test/functional/ios/ios/mjpeg_server_test.rb index 66f680c3..c3da2389 100644 --- a/test/functional/ios/ios/mjpeg_server_test.rb +++ b/test/functional/ios/ios/mjpeg_server_test.rb @@ -25,11 +25,11 @@ def test_config end def test_start_recording_screen - to_path = 'recorded_file_ios.mp4' + to_path = 'recorded_file_ios.avi' File.delete to_path if File.exist? to_path - @@driver.start_recording_screen time_limit: '2' - sleep 5 # second + @@driver.start_recording_screen time_limit: '2', video_type: 'mjpeg' + sleep 3 # second @@driver.stop_and_save_recording_screen to_path assert File.exist? to_path end From 2988925e59b40596b1f78a86fd44de992c375540 Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Wed, 21 Nov 2018 16:00:38 +0900 Subject: [PATCH 3/6] fix rubocop --- lib/appium_lib_core/ios/xcuitest/device/screen.rb | 4 ++-- test/unit/ios/device/mjsonwp/commands_test.rb | 10 ++++++---- test/unit/ios/device/w3c/commands_test.rb | 6 ++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/appium_lib_core/ios/xcuitest/device/screen.rb b/lib/appium_lib_core/ios/xcuitest/device/screen.rb index 05006ebe..7f6dc7a0 100644 --- a/lib/appium_lib_core/ios/xcuitest/device/screen.rb +++ b/lib/appium_lib_core/ios/xcuitest/device/screen.rb @@ -9,7 +9,7 @@ def self.add_methods # rubocop:disable Metrics/ParameterLists def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: nil, force_restart: nil, video_type: 'mjpeg', time_limit: '180', video_quality: 'medium', - video_fps: nil, video_scale: nil ) + video_fps: nil, video_scale: nil) option = ::Appium::Core::Base::Device::ScreenRecord.new( remote_path: remote_path, user: user, pass: pass, method: method, force_restart: force_restart ).upload_option @@ -19,7 +19,7 @@ def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: nil, option[:videoQuality] = video_quality option[:videoFps] = video_fps unless video_fps.nil? - option[:videoScale] = video_scale unless video_scale.nil? + option[:videoScale] = video_scale unless video_scale.nil? execute(:start_recording_screen, {}, { options: option }) end diff --git a/test/unit/ios/device/mjsonwp/commands_test.rb b/test/unit/ios/device/mjsonwp/commands_test.rb index b56282e5..92954f7d 100644 --- a/test/unit/ios/device/mjsonwp/commands_test.rb +++ b/test/unit/ios/device/mjsonwp/commands_test.rb @@ -46,10 +46,12 @@ def test_start_recording_screen def test_start_recording_screen_custom stub_request(:post, "#{SESSION}/appium/start_recording_screen") - .with(body: { options: { videoType: 'hevc', timeLimit: '60', videoQuality: 'medium', videoScale: '320:240' } }.to_json) + .with(body: { options: { + videoType: 'libx264', timeLimit: '60', videoQuality: 'medium', videoScale: '320:240' + } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) - @driver.start_recording_screen video_type: 'hevc', time_limit: '60', video_scale: '320:240' + @driver.start_recording_screen video_type: 'libx264', time_limit: '60', video_scale: '320:240' assert_requested(:post, "#{SESSION}/appium/start_recording_screen", times: 1) end @@ -57,10 +59,10 @@ def test_start_recording_screen_custom def test_start_recording_screen_custom_force stub_request(:post, "#{SESSION}/appium/start_recording_screen") .with(body: - { options: { forceRestart: true, videoType: 'hevc', timeLimit: '60', videoQuality: 'medium' } }.to_json) + { options: { forceRestart: true, videoType: 'libx264', timeLimit: '60', videoQuality: 'medium' } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) - @driver.start_recording_screen video_type: 'hevc', time_limit: '60', force_restart: true + @driver.start_recording_screen video_type: 'libx264', time_limit: '60', force_restart: true assert_requested(:post, "#{SESSION}/appium/start_recording_screen", times: 1) end diff --git a/test/unit/ios/device/w3c/commands_test.rb b/test/unit/ios/device/w3c/commands_test.rb index 2a5debcd..46f1482e 100644 --- a/test/unit/ios/device/w3c/commands_test.rb +++ b/test/unit/ios/device/w3c/commands_test.rb @@ -44,10 +44,12 @@ def test_start_recording_screen def test_start_recording_screen_custom stub_request(:post, "#{SESSION}/appium/start_recording_screen") - .with(body: { options: { videoType: 'hevc', timeLimit: '60', videoQuality: 'medium', videoFps: '50', videoScale: '320:240' } }.to_json) + .with(body: { options: { + videoType: 'libx264', timeLimit: '60', videoQuality: 'medium', videoFps: '50', videoScale: '320:240' + } }.to_json) .to_return(headers: HEADER, status: 200, body: { value: ['a'] }.to_json) - @driver.start_recording_screen video_type: 'hevc', time_limit: '60', video_fps: '50', video_scale: '320:240' + @driver.start_recording_screen video_type: 'libx264', time_limit: '60', video_fps: '50', video_scale: '320:240' assert_requested(:post, "#{SESSION}/appium/start_recording_screen", times: 1) end From 2b439a977f0515779d7ea3adcd0d311c0f72856d Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Wed, 21 Nov 2018 16:32:47 +0900 Subject: [PATCH 4/6] tweak a test scenario --- lib/appium_lib_core/ios/xcuitest/device.rb | 1 + test/functional/ios/ios/mjpeg_server_test.rb | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/appium_lib_core/ios/xcuitest/device.rb b/lib/appium_lib_core/ios/xcuitest/device.rb index c8b08c26..247d8926 100644 --- a/lib/appium_lib_core/ios/xcuitest/device.rb +++ b/lib/appium_lib_core/ios/xcuitest/device.rb @@ -41,6 +41,7 @@ module Device # # Record the display of devices running iOS Simulator since Xcode 9 or real devices since iOS 11 # (ffmpeg utility is required: 'brew install ffmpeg'). + # We would recommend to play the video by VLC or Mplayer if you can not play the video with other video players. # # @param [String] remote_path: The path to the remote location, where the resulting video should be uploaded. # The following protocols are supported: http/https, ftp. diff --git a/test/functional/ios/ios/mjpeg_server_test.rb b/test/functional/ios/ios/mjpeg_server_test.rb index c3da2389..f672e24b 100644 --- a/test/functional/ios/ios/mjpeg_server_test.rb +++ b/test/functional/ios/ios/mjpeg_server_test.rb @@ -28,8 +28,10 @@ def test_start_recording_screen to_path = 'recorded_file_ios.avi' File.delete to_path if File.exist? to_path - @@driver.start_recording_screen time_limit: '2', video_type: 'mjpeg' - sleep 3 # second + @@driver.start_recording_screen video_type: 'mjpeg' + @@driver.find_element(:accessibility_id, 'Buttons').click + sleep 2 # second + @@driver.back @@driver.stop_and_save_recording_screen to_path assert File.exist? to_path end From c4baf3fede612604668622fae3757b6e88ef08e1 Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Wed, 21 Nov 2018 16:33:35 +0900 Subject: [PATCH 5/6] tweak android scenario --- test/functional/android/android/mjpeg_server_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/android/android/mjpeg_server_test.rb b/test/functional/android/android/mjpeg_server_test.rb index 776f3ec2..5fa4819b 100644 --- a/test/functional/android/android/mjpeg_server_test.rb +++ b/test/functional/android/android/mjpeg_server_test.rb @@ -19,7 +19,7 @@ def test_start_recording_screen File.delete to_path if File.exist? to_path @@driver.start_recording_screen time_limit: '2' - @driver.find_element(:accessibility_id, 'App').click + @@driver.find_element(:accessibility_id, 'App').click sleep 2 # second @@driver.stop_and_save_recording_screen to_path assert File.exist? to_path From dfc2e9850c46a440a389b77e58969e136115970e Mon Sep 17 00:00:00 2001 From: Kazuaki MATSUO Date: Wed, 21 Nov 2018 17:52:52 +0900 Subject: [PATCH 6/6] update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d96230a..39dfb497 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ Read `release_notes.md` for commit level details. opts = { desired_capabilities: { }, appium_lib: { } } @driver = Appium::Core.for(opts).start_driver ``` +- Update `start_recording_screen` for iOS, Appium 1.10.0 + - Add `:video_scale` and update `:video_type` ### Bug fixes @@ -29,7 +31,7 @@ Read `release_notes.md` for commit level details. # 2 Appium::Core.for caps: {...}, appium_lib: {...} ``` -- Add `videoFps` param for screen recording in iOS(XCUITest) to sync with Appium 1.9.2 +- Add `:video_fps` param for screen recording in iOS(XCUITest) to sync with Appium 1.10.0 ### Bug fixes