test-recorder 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db491c5f3e52392c234291c174bbc1fff1bfb67d05a0ba23e50560529ea21d25
4
- data.tar.gz: ae3f23d20992e0ec4e9cc4597fa15e346e52e1d2c31e482eab750d64942f8df1
3
+ metadata.gz: 9ce916b59fcd166bdcafb222263423739c9c8fe58e53a50f5895c95485145522
4
+ data.tar.gz: 71fd0cb14988364e06d7977c38815a6656522c2acb79180ec06e5889b5eab155
5
5
  SHA512:
6
- metadata.gz: d4964d2703dc893155e0d246843141221e75991c57eb93da21e3c1331c9d9d648f56cf32d88885d4f89fc6da07b3889215549c055c9986aeecd3ac9c43bde1d7
7
- data.tar.gz: d4c944875e4ee763fa6b88c434e700afa63fd1c3380d392e2d18f589a3e6f15aae4c2c83a52ece118829b0b343581efbe8b4a9d982b291921715c4e72f553f31
6
+ metadata.gz: 3caaba9397db23c5c2bdb215812345af54f04a21e25c56ae6c83209c45f42a2bfd1891a587e7c58682ee85bd07b806d077adb7f7e780e2cd1c202fa2a38e5b64
7
+ data.tar.gz: 50f45dfc872ff6cc60a997f842bff3ba95d225cd88621879d2a07c0119c577376528ac3cedf306322c9c7efe1e18a1be63d232109c4d3ac29f3689d22aed27b9
@@ -1,6 +1,11 @@
1
1
  name: CI
2
2
 
3
- on: [push]
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+
8
+ pull_request:
4
9
 
5
10
  jobs:
6
11
  build:
@@ -11,13 +16,13 @@ jobs:
11
16
  cancel-in-progress: true
12
17
 
13
18
  steps:
14
- - uses: actions/checkout@v2
19
+ - uses: actions/checkout@v3
15
20
  - uses: ruby/setup-ruby@v1
16
21
  with:
17
- ruby-version: '3.0.3'
18
- - uses: actions/setup-node@v1
22
+ ruby-version: '3.2'
23
+ - uses: actions/setup-node@v2
19
24
  with:
20
- node-version: '14'
25
+ node-version: '18'
21
26
  - name: Install ffmpeg
22
27
  run: |
23
28
  sudo apt update && sudo apt install ffmpeg
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 0.2.0 - 2023-08-23
2
+
3
+ * Add support for aggregate_failures #21 (@willnet)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- test-recorder (0.1.4)
4
+ test-recorder (0.2.0)
5
5
  activesupport
6
6
  selenium-devtools
7
7
  selenium-webdriver (>= 4.0)
@@ -9,36 +9,35 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (7.0.3)
12
+ activesupport (7.0.7)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 1.6, < 2)
15
15
  minitest (>= 5.1)
16
16
  tzinfo (~> 2.0)
17
17
  activesupport-testing-metadata (0.1.0)
18
18
  activesupport (>= 4.0)
19
- childprocess (4.1.0)
20
- concurrent-ruby (1.1.10)
21
- debug (1.5.0)
22
- irb (>= 1.3.6)
23
- reline (>= 0.2.7)
24
- i18n (1.10.0)
19
+ concurrent-ruby (1.2.2)
20
+ debug (1.8.0)
21
+ irb (>= 1.5.0)
22
+ reline (>= 0.3.1)
23
+ i18n (1.14.1)
25
24
  concurrent-ruby (~> 1.0)
26
- io-console (0.5.11)
27
- irb (1.4.1)
28
- reline (>= 0.3.0)
29
- minitest (5.15.0)
25
+ io-console (0.6.0)
26
+ irb (1.7.4)
27
+ reline (>= 0.3.6)
28
+ minitest (5.19.0)
30
29
  rake (12.3.3)
31
- reline (0.3.1)
30
+ reline (0.3.8)
32
31
  io-console (~> 0.5)
33
- rexml (3.2.5)
32
+ rexml (3.2.6)
34
33
  rubyzip (2.3.2)
35
- selenium-devtools (0.101.0)
36
- websocket (~> 1.0)
37
- selenium-webdriver (4.1.0)
38
- childprocess (>= 0.5, < 5.0)
34
+ selenium-devtools (0.115.0)
35
+ selenium-webdriver (~> 4.2)
36
+ selenium-webdriver (4.11.0)
39
37
  rexml (~> 3.2, >= 3.2.5)
40
- rubyzip (>= 1.2.2)
41
- tzinfo (2.0.4)
38
+ rubyzip (>= 1.2.2, < 3.0)
39
+ websocket (~> 1.0)
40
+ tzinfo (2.0.6)
42
41
  concurrent-ruby (~> 1.0)
43
42
  websocket (1.2.9)
44
43
 
@@ -53,4 +52,4 @@ DEPENDENCIES
53
52
  test-recorder!
54
53
 
55
54
  BUNDLED WITH
56
- 2.2.32
55
+ 2.4.3
data/README.md CHANGED
@@ -5,6 +5,7 @@ Record a video automatically when tests failed. The videos are generated in `tmp
5
5
  [![Build Status](https://github.com/y-yagi/test-recorder/workflows/CI/badge.svg)](https://github.com/y-yagi/test-recorder/actions)
6
6
  [![Gem Version](https://badge.fury.io/rb/test-recorder.svg)](http://badge.fury.io/rb/test-recorder)
7
7
 
8
+ This gem was inspired by [Record video feature of Playwright](https://playwright.dev/docs/videos).
8
9
 
9
10
  ## Requirements
10
11
 
@@ -1,10 +1,13 @@
1
+ require "open3"
1
2
  require "fileutils"
3
+ require "tempfile"
2
4
 
3
5
  module TestRecorder
4
6
  class CdpRecorder
5
7
  def initialize(enabled:)
6
8
  @enabled = enabled
7
- @tmpdir = nil
9
+ @started = nil
10
+ @page = nil
8
11
  setup
9
12
  end
10
13
 
@@ -15,21 +18,20 @@ module TestRecorder
15
18
 
16
19
  def start(page:, enabled: nil)
17
20
  enabled = @enabled if enabled.nil?
18
- return unless enabled
21
+ @started = enabled
22
+ return unless @started
19
23
 
20
- @tmpdir = Dir.mktmpdir("testrecorder")
21
- counter = 1
24
+ @tmp_video = Tempfile.open(["testrecorder", ".webm"])
25
+ cmd = "ffmpeg -loglevel quiet -f image2pipe -avioflags direct -fpsprobesize 0 -probesize 32 -analyzeduration 0 -c:v mjpeg -i - -y -an -r 25 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M -threads 1 #{@tmp_video.path}"
26
+ @stdin, @wait_thrs = *Open3.pipeline_w(cmd)
27
+ @stdin.set_encoding("ASCII-8BIT")
22
28
 
23
29
  @page = page
24
30
  @page.driver.browser.devtools.page.enable
25
31
 
26
32
  @page.driver.browser.devtools.page.on(:screencast_frame) do |event|
27
33
  decoded_data = Base64.decode64(event["data"])
28
- filename = "%010d.jpeg" % counter
29
- if Dir.exist?(@tmpdir)
30
- IO.binwrite("#{File.join(@tmpdir, filename)}", decoded_data)
31
- counter += 1
32
- end
34
+ @stdin.print(decoded_data) rescue nil
33
35
  @page.driver.browser.devtools.page.screencast_frame_ack(session_id: event["sessionId"])
34
36
  end
35
37
 
@@ -37,25 +39,24 @@ module TestRecorder
37
39
  end
38
40
 
39
41
  def stop_and_discard
40
- FileUtils.rm_rf(@tmpdir) unless @tmpdir.nil?
42
+ if @started
43
+ @page.driver.browser.devtools.page.stop_screencast
44
+ @stdin.close
45
+ end
41
46
  end
42
47
 
43
48
  def stop_and_save(filename)
44
- return if @tmpdir.nil? || @page.nil?
49
+ return "" unless @started
45
50
 
46
51
  @page.driver.browser.devtools.page.stop_screencast
52
+ @stdin.close
53
+ @wait_thrs.each(&:join)
54
+
47
55
  video_path = File.join(@video_dir, filename)
56
+ FileUtils.copy(@tmp_video.path, video_path)
57
+ @tmp_video.close(true)
48
58
 
49
- args = %W(-loglevel error -f image2 -avioflags direct -fpsprobesize 0
50
- -probesize 32 -analyzeduration 0 -c:v mjpeg -i #{File.join(@tmpdir, "%010d.jpeg")}
51
- -y -an -r 25 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M
52
- -threads 1 #{video_path})
53
- system("ffmpeg", *args, exception: true)
54
59
  video_path
55
- rescue => e
56
- $stderr.puts("[TestRecorder] ffmpeg failed: #{e.message}")
57
- ensure
58
- FileUtils.rm_rf(@tmpdir)
59
60
  end
60
61
  end
61
62
  end
@@ -13,7 +13,7 @@ module TestRecorder
13
13
  if failures.empty?
14
14
  @cdp_recorder.stop_and_discard
15
15
  else
16
- video_path = @cdp_recorder.stop_and_save("failures_#{self.name}.mp4")
16
+ video_path = @cdp_recorder.stop_and_save("failures_#{self.name}.webm")
17
17
  puts "[Video]: #{video_path}" if File.exist?(video_path)
18
18
  end
19
19
  ensure
@@ -9,19 +9,29 @@ module TestRecorder
9
9
  attr_accessor :cdp_recorder
10
10
 
11
11
  def after_failed_example(example)
12
- if example.exception
13
- video_path = cdp_recorder.stop_and_save("failures_#{method_name(example)}.mp4").to_s
12
+ if passed?(example)
13
+ cdp_recorder.stop_and_discard
14
+ else
15
+ video_path = cdp_recorder.stop_and_save("failures_#{method_name(example)}.webm").to_s
14
16
  if File.exist?(video_path)
15
17
  example.metadata[:extra_failure_lines] = [example.metadata[:extra_failure_lines], "[Video]: #{video_path}"].flatten
16
18
  end
17
- else
18
- cdp_recorder.stop_and_discard
19
19
  end
20
20
  end
21
21
 
22
22
  def method_name(example)
23
23
  example.description.underscore.tr(CHARS_TO_TRANSLATE.join, "_")[0...200] + "_#{rand(1000)}"
24
24
  end
25
+
26
+ def passed?(example)
27
+ return false if example.exception
28
+ return true unless defined?(::RSpec::Expectations::FailureAggregator)
29
+
30
+ failure_notifier = ::RSpec::Support.failure_notifier
31
+ return true unless failure_notifier.is_a?(::RSpec::Expectations::FailureAggregator)
32
+
33
+ failure_notifier.failures.empty? && failure_notifier.other_errors.empty?
34
+ end
25
35
  end
26
36
  end
27
37
  end
@@ -1,3 +1,3 @@
1
1
  module TestRecorder
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-recorder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Yaginuma
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-11 00:00:00.000000000 Z
11
+ date: 2023-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -75,6 +75,7 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - ".github/workflows/ci.yml"
77
77
  - ".gitignore"
78
+ - CHANGELOG.md
78
79
  - Gemfile
79
80
  - Gemfile.lock
80
81
  - LICENSE.txt
@@ -111,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  - !ruby/object:Gem::Version
112
113
  version: '0'
113
114
  requirements: []
114
- rubygems_version: 3.2.32
115
+ rubygems_version: 3.4.10
115
116
  signing_key:
116
117
  specification_version: 4
117
118
  summary: Automatically record videos when tests failed.