test-recorder 0.1.0 → 0.1.1

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: 745f47568a578d0d76e8558dc16fd6277045cd86dca6a09f38b4914b90e09775
4
- data.tar.gz: 9ec908cb4e136d8137d5304c77594fd0d88e81070ff5b086198035e5cdef1d39
3
+ metadata.gz: e868dca992d2695188debf897102cd76ed6374a25abcb0bbd8875414f9714f9e
4
+ data.tar.gz: ecad80fbed7bc759ef3d30043b1fcdeb15202f3caa3a6e095b29e9d5ccf77e9c
5
5
  SHA512:
6
- metadata.gz: f3962a434f3c98a2dfdd9840cf60205795cc175a18b34d2eb3dd66f6c1ec43603f9b6bd53cc0970811e1cfd6cb54149bdef3db2858173db72769f75a191b750e
7
- data.tar.gz: 97b93c654e9125cf0732c803e49808d4fb6a72402827307708cd52853d21def581843c9d8da877b027206d322cebae31a9efab655f28617212adfc4e299152f2
6
+ metadata.gz: d13e0d7f4fe1056b99f367c08ea89424cfc86780a0d04754425098c7d9c9964f8abb675360a6fafd8c3e8db4fdb0e5f4b9d55890e2376dbf70391a2c3ddfac52
7
+ data.tar.gz: dccb98cfda3cf96ffd888f3cea87cc8cfd9d27631da0ce66408c410fbf1b74fc74c7ea45461c48ffe1c29cca1895d96c7716884189fe4e689ea7175c4dd6e480
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+
9
+ concurrency:
10
+ group: ${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: '3.0.3'
18
+ - uses: actions/setup-node@v1
19
+ with:
20
+ node-version: '14'
21
+ - name: Install ffmpeg
22
+ run: |
23
+ sudo apt install ffmpeg
24
+ - name: Install dependencies
25
+ run: |
26
+ gem install bundler --no-document
27
+ bundle install
28
+ - name: Run test
29
+ run: bundle exec rake
data/Gemfile.lock CHANGED
@@ -1,67 +1,36 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- test-recorder (0.1.0)
5
- headless
6
- railties
4
+ test-recorder (0.1.1)
5
+ activesupport
6
+ selenium-devtools
7
+ selenium-webdriver (>= 4.0)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
11
- actionpack (6.0.3.4)
12
- actionview (= 6.0.3.4)
13
- activesupport (= 6.0.3.4)
14
- rack (~> 2.0, >= 2.0.8)
15
- rack-test (>= 0.6.3)
16
- rails-dom-testing (~> 2.0)
17
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
18
- actionview (6.0.3.4)
19
- activesupport (= 6.0.3.4)
20
- builder (~> 3.1)
21
- erubi (~> 1.4)
22
- rails-dom-testing (~> 2.0)
23
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
24
- activesupport (6.0.3.4)
12
+ activesupport (7.0.0)
25
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
26
- i18n (>= 0.7, < 2)
27
- minitest (~> 5.1)
28
- tzinfo (~> 1.1)
29
- zeitwerk (~> 2.2, >= 2.2.2)
30
- builder (3.2.4)
31
- concurrent-ruby (1.1.7)
32
- crass (1.0.6)
33
- erubi (1.9.0)
34
- headless (2.3.1)
35
- i18n (1.8.5)
14
+ i18n (>= 1.6, < 2)
15
+ minitest (>= 5.1)
16
+ tzinfo (~> 2.0)
17
+ childprocess (4.1.0)
18
+ concurrent-ruby (1.1.9)
19
+ i18n (1.8.11)
36
20
  concurrent-ruby (~> 1.0)
37
- loofah (2.7.0)
38
- crass (~> 1.0.2)
39
- nokogiri (>= 1.5.9)
40
- method_source (1.0.0)
41
- mini_portile2 (2.4.0)
42
21
  minitest (5.14.2)
43
- nokogiri (1.10.10)
44
- mini_portile2 (~> 2.4.0)
45
- rack (2.2.3)
46
- rack-test (1.1.0)
47
- rack (>= 1.0, < 3)
48
- rails-dom-testing (2.0.3)
49
- activesupport (>= 4.2.0)
50
- nokogiri (>= 1.6)
51
- rails-html-sanitizer (1.3.0)
52
- loofah (~> 2.3)
53
- railties (6.0.3.4)
54
- actionpack (= 6.0.3.4)
55
- activesupport (= 6.0.3.4)
56
- method_source
57
- rake (>= 0.8.7)
58
- thor (>= 0.20.3, < 2.0)
59
22
  rake (12.3.3)
60
- thor (1.0.1)
61
- thread_safe (0.3.6)
62
- tzinfo (1.2.7)
63
- thread_safe (~> 0.1)
64
- zeitwerk (2.4.0)
23
+ rexml (3.2.5)
24
+ rubyzip (2.3.2)
25
+ selenium-devtools (0.96.0)
26
+ websocket (~> 1.0)
27
+ selenium-webdriver (4.1.0)
28
+ childprocess (>= 0.5, < 5.0)
29
+ rexml (~> 3.2, >= 3.2.5)
30
+ rubyzip (>= 1.2.2)
31
+ tzinfo (2.0.4)
32
+ concurrent-ruby (~> 1.0)
33
+ websocket (1.2.9)
65
34
 
66
35
  PLATFORMS
67
36
  ruby
@@ -72,4 +41,4 @@ DEPENDENCIES
72
41
  test-recorder!
73
42
 
74
43
  BUNDLED WITH
75
- 2.1.4
44
+ 2.2.32
data/README.md CHANGED
@@ -1,3 +1,49 @@
1
- # Videotest::Recorder
1
+ # TestRecorder
2
2
 
3
- :hammer_and_pick: WIP :hammer_and_pick:
3
+ Record a video automatically when tests failed. The videos are generated in `tmp/videos` directory.
4
+
5
+ ![CI](https://github.com/y-yagi/test-recorder/workflows/CI/badge.svg)
6
+ [![Gem Version](https://badge.fury.io/rb/test-recorder.svg)](http://badge.fury.io/rb/test-recorder)
7
+
8
+
9
+ ## Requirements
10
+
11
+ This gem depends on FFmpeg. Please install that package.
12
+
13
+ On Debian/Ubuntu:
14
+
15
+ ```bash
16
+ sudo apt-get install ffmpeg
17
+ ```
18
+
19
+ ## Supported libraries
20
+
21
+ Rails system tests and RSpec(System Spec and Feature Spec).
22
+
23
+ ## Limitations
24
+
25
+ Currently, this gem only supports a Chrome headless.
26
+
27
+ ## Usage
28
+
29
+ ### 1: Install the gem
30
+
31
+ Using Bundler, add the following to your Gemfile:
32
+
33
+ ```ruby
34
+ gem 'test-recorder', group: :test
35
+ ```
36
+
37
+ ### 2: Load library into your tests
38
+
39
+ #### Rails
40
+
41
+ ```ruby
42
+ require 'test_recorder/rails'
43
+ ```
44
+
45
+ #### RSpec
46
+
47
+ ```ruby
48
+ require 'test_recorder/rspec'
49
+ ```
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ Rake::TestTask.new(:test) do |t|
6
6
  t.libs << "lib"
7
7
  t.verbose = true
8
8
  t.warning = true
9
- t.test_files = FileList["test/**/*_test.rb"]
9
+ t.test_files = ["test/integration_test.rb"]
10
10
  end
11
11
 
12
12
  task :default => :test
@@ -0,0 +1,59 @@
1
+ require "fileutils"
2
+
3
+ module TestRecorder
4
+ class CdpRecorder
5
+ def initialize(enabled:)
6
+ @enabled = enabled
7
+ setup if @enabled
8
+ end
9
+
10
+ def setup
11
+ @video_dir = ::Rails.root.join("tmp", "videos")
12
+ FileUtils.mkdir_p(@video_dir)
13
+ end
14
+
15
+ def start(page:)
16
+ return unless @enabled
17
+
18
+ @tmpdir = Dir.mktmpdir("testrecorder")
19
+ @counter = 1
20
+
21
+ @page = page
22
+ @page.driver.browser.devtools.page.enable
23
+
24
+ @page.driver.browser.devtools.page.on(:screencast_frame) do |event|
25
+ decoded_data = Base64.decode64(event["data"])
26
+ filename = "%010d.jpeg" % @counter
27
+ if Dir.exist?(@tmpdir)
28
+ IO.binwrite("#{File.join(@tmpdir, filename)}", decoded_data)
29
+ @counter += 1
30
+ end
31
+ @page.driver.browser.devtools.page.screencast_frame_ack(session_id: event["sessionId"])
32
+ end
33
+
34
+ @page.driver.browser.devtools.page.start_screencast(format: "jpeg", quality: 90)
35
+ end
36
+
37
+ def stop_and_discard
38
+ FileUtils.rm_rf(@tmpdir)
39
+ end
40
+
41
+ def stop_and_save(filename)
42
+ return if !@enabled || @page.nil?
43
+
44
+ @page.driver.browser.devtools.page.stop_screencast
45
+ video_path = File.join(@video_dir, filename)
46
+
47
+ args = %W(-loglevel error -f image2 -avioflags direct -fpsprobesize 0
48
+ -probesize 32 -analyzeduration 0 -c:v mjpeg -i #{File.join(@tmpdir, "%010d.jpeg")}
49
+ -y -an -r 25 -qmin 0 -qmax 50 -crf 8 -deadline realtime -speed 8 -b:v 1M
50
+ -threads 1 #{video_path})
51
+ system("ffmpeg", *args, exception: true)
52
+ video_path
53
+ rescue => e
54
+ $stderr.puts("[TestRecorder] ffmpeg failed: #{e.message}")
55
+ ensure
56
+ FileUtils.rm_rf(@tmpdir)
57
+ end
58
+ end
59
+ end
@@ -1,30 +1,21 @@
1
- require "headless"
2
1
  require "fileutils"
3
2
 
4
3
  module TestRecorder
5
4
  module Rails
6
5
  module SetupAndTeardown
7
- attr_reader :video_dir, :headless
8
-
9
6
  def before_setup
10
- @video_dir = ::Rails.root.join("tmp", "videos")
11
- FileUtils.mkdir_p(video_dir)
12
-
13
- # TODO: Allow configuring parameters.
14
- @headless = Headless.new(video: { provider: :ffmpeg, codec: :libx264, extra: %w(-preset ultrafast) })
15
- headless.start
16
- headless.video.start_capture
7
+ @cdp_recorder = TestRecorder::CdpRecorder.new(enabled: true)
8
+ @cdp_recorder.start(page: page)
17
9
 
18
10
  super
19
11
  end
20
12
 
21
13
  def before_teardown
22
14
  if failures.empty?
23
- headless.video.stop_and_discard
15
+ @cdp_recorder.stop_and_discard
24
16
  else
25
- video = video_dir.join("failures_#{self.name}.mp4")
26
- headless.video.stop_and_save(video)
27
- puts "[Video]: #{video}"
17
+ video_path = @cdp_recorder.stop_and_save("failures_#{self.name}.mp4")
18
+ puts "[Video]: #{video_path}" if File.exist?(video_path)
28
19
  end
29
20
  ensure
30
21
  super
@@ -1,3 +1,4 @@
1
+ require "test_recorder/cdp_recorder"
1
2
  require "test_recorder/rails/setup_and_teardown"
2
3
 
3
4
  ActiveSupport.on_load(:action_dispatch_system_test_case) do
@@ -0,0 +1,10 @@
1
+ module TestRecorder
2
+ module RSpec
3
+ module ExampleWrapper
4
+ def run_before_example
5
+ super
6
+ TestRecorder::RSpec.cdp_recorder.start(page: @example_group_instance.page)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,20 +1,21 @@
1
- require "headless"
2
- require "fileutils"
1
+ require "test_recorder/cdp_recorder"
2
+ require "test_recorder/rspec/example_wrapper"
3
3
 
4
4
  module TestRecorder
5
- module Rspec
5
+ module RSpec
6
6
  CHARS_TO_TRANSLATE = ['/', '.', ':', ',', "'", '"', " "].freeze
7
7
 
8
8
  class << self
9
- attr_accessor :headless, :video_dir
9
+ attr_accessor :cdp_recorder
10
10
 
11
11
  def after_failed_example(example)
12
12
  if example.exception
13
- video = video_dir.join("failures_#{method_name(example)}.mp4")
14
- headless.video.stop_and_save(video)
15
- example.metadata[:extra_failure_lines] = [example.metadata[:extra_failure_lines], "[Video]: #{video}"]
13
+ video_path = cdp_recorder.stop_and_save("failures_#{method_name(example)}.mp4").to_s
14
+ if File.exist?(video_path)
15
+ example.metadata[:extra_failure_lines] = [example.metadata[:extra_failure_lines], "[Video]: #{video_path}"].flatten
16
+ end
16
17
  else
17
- headless.video.stop_and_discard
18
+ cdp_recorder.stop_and_discard
18
19
  end
19
20
  end
20
21
 
@@ -25,21 +26,16 @@ module TestRecorder
25
26
  end
26
27
  end
27
28
 
28
- RSpec.configure do |config|
29
- config.before do
30
- TestRecorder::Rspec.video_dir = ::Rails.root.join("tmp", "videos")
31
- FileUtils.mkdir_p(TestRecorder::Rspec.video_dir)
29
+ RSpec::Core::Example.prepend(TestRecorder::RSpec::ExampleWrapper)
32
30
 
33
- TestRecorder::Rspec.headless = Headless.new(video: { provider: :ffmpeg, codec: :libx264, extra: %w(-preset ultrafast) })
34
- TestRecorder::Rspec.headless.start
35
- TestRecorder::Rspec.headless.video.start_capture
36
- end
31
+ RSpec.configure do |config|
32
+ TestRecorder::RSpec.cdp_recorder = TestRecorder::CdpRecorder.new(enabled: true)
37
33
 
38
34
  config.after(type: :system) do |example|
39
- TestRecorder::Rspec.after_failed_example(example)
35
+ TestRecorder::RSpec.after_failed_example(example)
40
36
  end
41
37
 
42
38
  config.after(type: :feature) do |example|
43
- TestRecorder::Rspec.after_failed_example(example)
39
+ TestRecorder::RSpec.after_failed_example(example)
44
40
  end
45
41
  end
@@ -1,3 +1,3 @@
1
1
  module TestRecorder
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.bindir = "exe"
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
- spec.add_dependency "headless"
23
- spec.add_dependency "railties"
22
+ spec.add_dependency "activesupport"
23
+ spec.add_dependency "selenium-webdriver", ">= 4.0"
24
+ spec.add_dependency "selenium-devtools"
24
25
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test-recorder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Yaginuma
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-23 00:00:00.000000000 Z
11
+ date: 2022-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: headless
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: railties
28
+ name: selenium-webdriver
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: selenium-devtools
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -45,6 +59,7 @@ executables: []
45
59
  extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
62
+ - ".github/workflows/ci.yml"
48
63
  - ".gitignore"
49
64
  - Gemfile
50
65
  - Gemfile.lock
@@ -55,9 +70,11 @@ files:
55
70
  - bin/setup
56
71
  - lib/test-recorder.rb
57
72
  - lib/test_recorder.rb
73
+ - lib/test_recorder/cdp_recorder.rb
58
74
  - lib/test_recorder/rails.rb
59
75
  - lib/test_recorder/rails/setup_and_teardown.rb
60
76
  - lib/test_recorder/rspec.rb
77
+ - lib/test_recorder/rspec/example_wrapper.rb
61
78
  - lib/test_recorder/version.rb
62
79
  - test-recorder.gemspec
63
80
  homepage: http://github.com/y-yagi/test-recorder
@@ -80,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
97
  - !ruby/object:Gem::Version
81
98
  version: '0'
82
99
  requirements: []
83
- rubygems_version: 3.1.2
100
+ rubygems_version: 3.2.32
84
101
  signing_key:
85
102
  specification_version: 4
86
103
  summary: Automatically record videos when tests failed.