bidi2pdf 0.1.7 โ†’ 0.1.9

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -8
  3. data/README.md +14 -0
  4. data/docker/Dockerfile.chromedriver +30 -5
  5. data/docker/entrypoint.sh +41 -0
  6. data/lib/bidi2pdf/bidi/browser_tab.rb +59 -8
  7. data/lib/bidi2pdf/bidi/client.rb +7 -5
  8. data/lib/bidi2pdf/bidi/command_manager.rb +14 -26
  9. data/lib/bidi2pdf/bidi/connection_manager.rb +3 -9
  10. data/lib/bidi2pdf/bidi/event_manager.rb +35 -5
  11. data/lib/bidi2pdf/bidi/interceptor.rb +12 -2
  12. data/lib/bidi2pdf/bidi/navigation_failed_events.rb +41 -0
  13. data/lib/bidi2pdf/bidi/session.rb +6 -1
  14. data/lib/bidi2pdf/bidi/web_socket_dispatcher.rb +5 -5
  15. data/lib/bidi2pdf/chromedriver_manager.rb +25 -11
  16. data/lib/bidi2pdf/notifications.rb +1 -1
  17. data/lib/bidi2pdf/test_helpers/matchers/contains_pdf_text.rb +50 -0
  18. data/lib/bidi2pdf/test_helpers/matchers/have_pdf_page_count.rb +50 -0
  19. data/lib/bidi2pdf/test_helpers/matchers/match_pdf_text.rb +45 -0
  20. data/lib/bidi2pdf/test_helpers/pdf_reader_utils.rb +89 -0
  21. data/lib/bidi2pdf/test_helpers/pdf_text_sanitizer.rb +232 -0
  22. data/lib/bidi2pdf/test_helpers/testcontainers/chromedriver_container.rb +81 -0
  23. data/lib/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rb +103 -0
  24. data/lib/bidi2pdf/test_helpers/testcontainers/shared_docker_network.rb +21 -0
  25. data/lib/bidi2pdf/test_helpers/testcontainers/testcontainers_refinement.rb +53 -0
  26. data/lib/bidi2pdf/test_helpers/testcontainers.rb +17 -0
  27. data/lib/bidi2pdf/test_helpers.rb +13 -0
  28. data/lib/bidi2pdf/version.rb +1 -1
  29. data/lib/bidi2pdf.rb +32 -3
  30. data/sig/bidi2pdf/bidi/event_manager.rbs +19 -13
  31. metadata +35 -6
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "shared_docker_network"
4
+
5
+ module Bidi2pdf
6
+ module TestHelpers
7
+ module Testcontainers
8
+ module ChromedriverTestHelper
9
+ def session_url
10
+ chromedriver_container.session_url
11
+ end
12
+
13
+ def chromedriver_container
14
+ RSpec.configuration.chromedriver_container
15
+ end
16
+ end
17
+
18
+ module SessionTestHelper
19
+ def chrome_args
20
+ chrome_args = Bidi2pdf::Bidi::Session::DEFAULT_CHROME_ARGS.dup
21
+
22
+ # within github actions, the sandbox is not supported, when we start our own container
23
+ # some privileges are not available ???
24
+ if ENV["DISABLE_CHROME_SANDBOX"]
25
+ chrome_args << "--no-sandbox"
26
+
27
+ puts "๐Ÿšจ Chrome sandbox disabled"
28
+ end
29
+ chrome_args
30
+ end
31
+
32
+ def create_session(session_url)
33
+ Bidi2pdf::Bidi::Session.new(session_url: session_url, headless: true, chrome_args: chrome_args)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ RSpec.configure do |config|
41
+ config.add_setting :chromedriver_container, default: nil
42
+
43
+ config.include Bidi2pdf::TestHelpers::Testcontainers::ChromedriverTestHelper, chromedriver: true
44
+ config.include Bidi2pdf::TestHelpers::Testcontainers::SessionTestHelper, session: true
45
+
46
+ config.before(:suite) do
47
+ if chromedriver_tests_present?
48
+ config.chromedriver_container = start_chromedriver_container(
49
+ build_dir: File.join(config.docker_dir, ".."),
50
+ mounts: config.respond_to?(:chromedriver_mounts) ? config.chromedriver_mounts : {},
51
+ shared_network: config.shared_network
52
+ )
53
+
54
+ puts "๐Ÿš€ chromedriver container started for tests"
55
+ end
56
+ end
57
+
58
+ config.after(:suite) do
59
+ stop_container config.chromedriver_container
60
+ end
61
+ end
62
+
63
+ def stop_container(container)
64
+ if container&.running?
65
+
66
+ if ENV["SHOW_CONTAINER_LOGS"]
67
+ puts "Container logs:"
68
+ logs_std, logs_error = container.logs
69
+
70
+ puts logs_error
71
+ puts logs_std
72
+ end
73
+
74
+ puts "๐Ÿงน #{container.image} stopping container..."
75
+ container.stop
76
+ end
77
+ container&.remove
78
+ end
79
+
80
+ def chromedriver_tests_present?
81
+ test_of_kind_present? :chromedriver
82
+ end
83
+
84
+ def test_of_kind_present?(type)
85
+ RSpec.world.filtered_examples.values.flatten.any? { |example| example.metadata[type] }
86
+ end
87
+
88
+ # alias the long class name
89
+ ChromedriverTestcontainer = Bidi2pdf::TestHelpers::Testcontainers::ChromedriverContainer
90
+
91
+ def start_chromedriver_container(build_dir:, mounts:, shared_network:)
92
+ container = ChromedriverTestcontainer.new(ChromedriverTestcontainer::DEFAULT_IMAGE,
93
+ build_dir: build_dir,
94
+ docker_file: "docker/Dockerfile.chromedriver")
95
+ .with_network(shared_network)
96
+ .with_network_aliases("remote-chrome")
97
+
98
+ container.with_filesystem_binds(mounts) if mounts&.any?
99
+
100
+ container.start
101
+
102
+ container
103
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |config|
4
+ config.add_setting :shared_network, default: nil
5
+
6
+ config.before(:suite) do
7
+ examples = RSpec.world.filtered_examples.values.flatten
8
+ uses_containers = examples.any? do |ex|
9
+ ex.metadata[:nginx] || ex.metadata[:chrome] || ex.metadata[:chromedriver] || ex.metadata[:container]
10
+ end
11
+
12
+ if uses_containers
13
+ config.shared_network = Docker::Network.create("bidi2pdf-test-net-#{SecureRandom.hex(4)}")
14
+ puts "๐Ÿ•ธ๏ธ started shared network #{config.shared_network}"
15
+ end
16
+ end
17
+
18
+ config.after(:suite) do
19
+ config.shared_network&.remove
20
+ end
21
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bidi2pdf
4
+ module TestHelpers
5
+ module TestcontainersRefinement
6
+ def id
7
+ @_id
8
+ end
9
+
10
+ def aliases
11
+ @aliases ||= []
12
+ end
13
+
14
+ def aliases=(aliases)
15
+ @aliases = aliases
16
+ end
17
+
18
+ def network
19
+ @_network
20
+ end
21
+
22
+ def with_network(network)
23
+ @_network = network
24
+ self
25
+ end
26
+
27
+ def with_network_aliases(*aliases)
28
+ self.aliases += aliases
29
+ self
30
+ end
31
+
32
+ def _container_create_options
33
+ opts = super
34
+ network_name = network ? network.info["Name"] : nil
35
+ opts["HostConfig"]["NetworkMode"] = network_name
36
+
37
+ if network && aliases.any?
38
+ opts["NetworkingConfig"] = {
39
+ "EndpointsConfig" => {
40
+ network_name => {
41
+ "Aliases" => aliases
42
+ }
43
+ }
44
+ }
45
+ end
46
+
47
+ opts.compact
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ Testcontainers::DockerContainer.prepend(Bidi2pdf::TestHelpers::TestcontainersRefinement)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ %w[docker testcontainers].each do |dep|
4
+ require dep
5
+ rescue LoadError
6
+ warn "Missing #{dep}. Add it to your Gemfile if you're using Bidi2pdf test helpers."
7
+ end
8
+
9
+ module Bidi2pdf
10
+ module TestHelpers
11
+ module Testcontainers
12
+ require_relative "testcontainers/testcontainers_refinement"
13
+ require_relative "testcontainers/chromedriver_container"
14
+ require_relative "testcontainers/chromedriver_test_helper"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ %w[pdf-reader diff-lcs unicode_utils].each do |dep|
4
+ require dep
5
+ rescue LoadError
6
+ warn "Missing #{dep}. Add it to your Gemfile if you're using Bidi2pdf test helpers."
7
+ end
8
+
9
+ require "bidi2pdf/test_helpers/pdf_text_sanitizer"
10
+ require "bidi2pdf/test_helpers/pdf_reader_utils"
11
+ require "bidi2pdf/test_helpers/matchers/match_pdf_text"
12
+ require "bidi2pdf/test_helpers/matchers/contains_pdf_text"
13
+ require "bidi2pdf/test_helpers/matchers/have_pdf_page_count"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bidi2pdf
4
- VERSION = "0.1.7"
4
+ VERSION = "0.1.9"
5
5
  end
data/lib/bidi2pdf.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "concurrent-ruby"
4
+ require "logger"
5
+
3
6
  require_relative "bidi2pdf/process_tree"
4
7
  require_relative "bidi2pdf/launcher"
5
8
  require_relative "bidi2pdf/bidi/session"
@@ -8,8 +11,6 @@ require_relative "bidi2pdf/notifications"
8
11
  require_relative "bidi2pdf/notifications/logging_subscriber"
9
12
  require_relative "bidi2pdf/verbose_logger"
10
13
 
11
- require "logger"
12
-
13
14
  module Bidi2pdf
14
15
  PAPER_FORMATS_CM = {
15
16
  letter: { width: 21.59, height: 27.94 },
@@ -33,7 +34,16 @@ module Bidi2pdf
33
34
 
34
35
  class ClientError < WebsocketError; end
35
36
 
36
- class CmdError < ClientError; end
37
+ class CmdError < ClientError
38
+ attr_reader :cmd, :response
39
+
40
+ def initialize(cmd, response)
41
+ @cmd = cmd
42
+ @response = response
43
+
44
+ super("Error response: #{response["error"]} #{cmd.inspect}")
45
+ end
46
+ end
37
47
 
38
48
  class CmdResponseNotStoredError < ClientError; end
39
49
 
@@ -55,6 +65,25 @@ module Bidi2pdf
55
65
  end
56
66
  end
57
67
 
68
+ class NavigationError < Error; end
69
+
70
+ class NavigationAuthError < NavigationError
71
+ attr_reader :url
72
+
73
+ def initialize(url, message = nil)
74
+ @url = url
75
+ super("Navigation to #{url} failed due to authentication error. #{message}")
76
+ end
77
+ end
78
+
79
+ class NavigationTimeoutError < NavigationError; end
80
+
81
+ class NavigationNotFoundError < NavigationError; end
82
+
83
+ class NavigationDNSError < NavigationError; end
84
+
85
+ # Global configuration for Bidi2pdf
86
+
58
87
  class << self
59
88
  attr_accessor :default_timeout, :enable_default_logging_subscriber
60
89
  attr_reader :logging_subscriber, :logger, :network_events_logger, :browser_console_logger, :notification_service
@@ -1,29 +1,35 @@
1
1
  module Bidi2pdf
2
2
  module Bidi
3
3
  class EventManager
4
- @browser: Bidi2pdf::Bidi::Browser
5
- @listeners: Hash[String, Array[Proc]]
6
- @active: bool
4
+ class Listener
5
+ attr_reader block: untyped
6
+ attr_reader id: String
7
7
 
8
- def initialize: (browser: Bidi2pdf::Bidi::Browser) -> void
8
+ def initialize: (untyped block, ?String id) -> void
9
9
 
10
- def on: (String event_name) { (Hash[String, untyped]) -> void } -> void
10
+ def call: (*untyped args) -> untyped
11
11
 
12
- def off: (String event_name) -> void
12
+ def ==: (untyped other) -> bool
13
13
 
14
- def emit: (String event_name, Hash[String, untyped] params) -> void
14
+ def eql?: (untyped other) -> bool
15
15
 
16
- def start_listening: () -> void
16
+ def hash: () -> Integer
17
+ end
17
18
 
18
- def stop_listening: () -> void
19
+ @listeners: untyped
20
+ @type: untyped
19
21
 
20
- private
22
+ attr_reader type: untyped
21
23
 
22
- def register_browser_events: () -> void
24
+ def initialize: (untyped type) -> void
23
25
 
24
- def handle_event: (String event_name, Hash[String, untyped] params) -> void
26
+ def on: (*untyped event_names, &untyped block) -> Listener
25
27
 
26
- def process_event: (String event_name, Hash[String, untyped] params) -> void
28
+ def off: (untyped event_name, Listener listener) -> void
29
+
30
+ def dispatch: (untyped event_name, *untyped args) -> void
31
+
32
+ def clear: (?untyped event_name) -> void
27
33
  end
28
34
  end
29
35
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bidi2pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dieter S.
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-04-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: base64
@@ -38,6 +37,26 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: concurrent-ruby
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 1.3.1
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '1.0'
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 1.3.1
41
60
  - !ruby/object:Gem::Dependency
42
61
  name: json
43
62
  requirement: !ruby/object:Gem::Requirement
@@ -379,6 +398,7 @@ files:
379
398
  - lib/bidi2pdf/bidi/interceptor.rb
380
399
  - lib/bidi2pdf/bidi/js_logger_helper.rb
381
400
  - lib/bidi2pdf/bidi/logger_events.rb
401
+ - lib/bidi2pdf/bidi/navigation_failed_events.rb
382
402
  - lib/bidi2pdf/bidi/network_event.rb
383
403
  - lib/bidi2pdf/bidi/network_event_formatters.rb
384
404
  - lib/bidi2pdf/bidi/network_event_formatters/network_event_console_formatter.rb
@@ -398,6 +418,17 @@ files:
398
418
  - lib/bidi2pdf/notifications/logging_subscriber.rb
399
419
  - lib/bidi2pdf/process_tree.rb
400
420
  - lib/bidi2pdf/session_runner.rb
421
+ - lib/bidi2pdf/test_helpers.rb
422
+ - lib/bidi2pdf/test_helpers/matchers/contains_pdf_text.rb
423
+ - lib/bidi2pdf/test_helpers/matchers/have_pdf_page_count.rb
424
+ - lib/bidi2pdf/test_helpers/matchers/match_pdf_text.rb
425
+ - lib/bidi2pdf/test_helpers/pdf_reader_utils.rb
426
+ - lib/bidi2pdf/test_helpers/pdf_text_sanitizer.rb
427
+ - lib/bidi2pdf/test_helpers/testcontainers.rb
428
+ - lib/bidi2pdf/test_helpers/testcontainers/chromedriver_container.rb
429
+ - lib/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rb
430
+ - lib/bidi2pdf/test_helpers/testcontainers/shared_docker_network.rb
431
+ - lib/bidi2pdf/test_helpers/testcontainers/testcontainers_refinement.rb
401
432
  - lib/bidi2pdf/verbose_logger.rb
402
433
  - lib/bidi2pdf/version.rb
403
434
  - sig/bidi2pdf.rbs
@@ -456,7 +487,6 @@ metadata:
456
487
  source_code_uri: https://github.com/dieter-medium/bidi2pdf
457
488
  changelog_uri: https://github.com/dieter-medium/bidi2pdf/blob/master/CHANGELOG.md
458
489
  rubygems_mfa_required: 'true'
459
- post_install_message:
460
490
  rdoc_options: []
461
491
  require_paths:
462
492
  - lib
@@ -471,8 +501,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
471
501
  - !ruby/object:Gem::Version
472
502
  version: '0'
473
503
  requirements: []
474
- rubygems_version: 3.5.11
475
- signing_key:
504
+ rubygems_version: 3.6.8
476
505
  specification_version: 4
477
506
  summary: A Ruby gem that generates PDFs from web pages using Chrome's BiDi protocol,
478
507
  providing high-quality PDF documents from any URL with full support for modern web