bidi2pdf 0.1.6 → 0.1.8

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/CHANGELOG.md +63 -8
  4. data/README.md +28 -0
  5. data/docker/Dockerfile +1 -1
  6. data/docker/Dockerfile.chromedriver +9 -2
  7. data/docker/Dockerfile.slim +2 -2
  8. data/lib/bidi2pdf/bidi/browser_console_logger.rb +92 -0
  9. data/lib/bidi2pdf/bidi/browser_tab.rb +431 -41
  10. data/lib/bidi2pdf/bidi/client.rb +85 -23
  11. data/lib/bidi2pdf/bidi/command_manager.rb +46 -60
  12. data/lib/bidi2pdf/bidi/commands/base.rb +39 -1
  13. data/lib/bidi2pdf/bidi/commands/browser_remove_user_context.rb +27 -0
  14. data/lib/bidi2pdf/bidi/commands/browsing_context_print.rb +4 -0
  15. data/lib/bidi2pdf/bidi/commands/print_parameters_validator.rb +5 -0
  16. data/lib/bidi2pdf/bidi/commands.rb +1 -0
  17. data/lib/bidi2pdf/bidi/connection_manager.rb +3 -9
  18. data/lib/bidi2pdf/bidi/event_manager.rb +2 -2
  19. data/lib/bidi2pdf/bidi/interceptor.rb +1 -1
  20. data/lib/bidi2pdf/bidi/js_logger_helper.rb +16 -0
  21. data/lib/bidi2pdf/bidi/logger_events.rb +25 -45
  22. data/lib/bidi2pdf/bidi/navigation_failed_events.rb +41 -0
  23. data/lib/bidi2pdf/bidi/network_event.rb +15 -0
  24. data/lib/bidi2pdf/bidi/network_event_formatters/network_event_console_formatter.rb +4 -3
  25. data/lib/bidi2pdf/bidi/network_events.rb +27 -17
  26. data/lib/bidi2pdf/bidi/session.rb +123 -13
  27. data/lib/bidi2pdf/bidi/user_context.rb +62 -0
  28. data/lib/bidi2pdf/bidi/web_socket_dispatcher.rb +7 -7
  29. data/lib/bidi2pdf/chromedriver_manager.rb +48 -21
  30. data/lib/bidi2pdf/cli.rb +10 -2
  31. data/lib/bidi2pdf/dsl.rb +33 -0
  32. data/lib/bidi2pdf/launcher.rb +30 -0
  33. data/lib/bidi2pdf/notifications/event.rb +52 -0
  34. data/lib/bidi2pdf/notifications/instrumenter.rb +65 -0
  35. data/lib/bidi2pdf/notifications/logging_subscriber.rb +136 -0
  36. data/lib/bidi2pdf/notifications.rb +78 -0
  37. data/lib/bidi2pdf/session_runner.rb +35 -3
  38. data/lib/bidi2pdf/test_helpers/matchers/contains_pdf_text.rb +50 -0
  39. data/lib/bidi2pdf/test_helpers/matchers/have_pdf_page_count.rb +50 -0
  40. data/lib/bidi2pdf/test_helpers/matchers/match_pdf_text.rb +45 -0
  41. data/lib/bidi2pdf/test_helpers/pdf_reader_utils.rb +89 -0
  42. data/lib/bidi2pdf/test_helpers/pdf_text_sanitizer.rb +232 -0
  43. data/lib/bidi2pdf/test_helpers/testcontainers/chromedriver_container.rb +87 -0
  44. data/lib/bidi2pdf/test_helpers.rb +13 -0
  45. data/lib/bidi2pdf/verbose_logger.rb +79 -0
  46. data/lib/bidi2pdf/version.rb +1 -1
  47. data/lib/bidi2pdf.rb +131 -10
  48. data/sig/bidi2pdf/bidi/client.rbs +1 -1
  49. metadata +67 -4
  50. data/lib/bidi2pdf/utils.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 541e9193b3285383b2a82065b173af87c68edeb08ec157125761f44285118dff
4
- data.tar.gz: ab12e33ad21e8377ef964aa12d0d9b0ba757ee941c217febe6d46fb1cc381d5e
3
+ metadata.gz: d71c88a5941411b13770993de9b38f6321c263765ffce1a9bbd347fb960855ac
4
+ data.tar.gz: aa64333d4dc4de54f6e1b627287a5d11661634f3244a8e3a213428c243f155f1
5
5
  SHA512:
6
- metadata.gz: 91be15b3310098c7f16153331fa0a27a8b869dfebc9f3720a7da26d2c59b8444f266e21e93d74891b423e50d8223b01b2198f230753d38ad523b8c846c12150f
7
- data.tar.gz: 504516ecc1eac40e6c6e159c5f14aafdeb9d23bc587fcf6914ab60d8676a930a7866d6d0c07998398359c402780584f1e5b317c274dd6f3dba0ba50c1a73cbe6
6
+ metadata.gz: 1d598fe002552f46e53f803f46577adceeeb087b377a40b486d5d2ef7bf713463f429aa26b2687fb7d0b865d73aacf3262be71e17db154794ac82e1e4a245986
7
+ data.tar.gz: 3b7cb02b0e857e551c720a665ac31d3669a9a27e8c9e3e5c1cdc497517b8fbcd3e917d6b0735113e3b956b23ded042b44c72bfff637cfdbf2431642bd98aaa2b
data/.rubocop.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  AllCops:
2
2
  NewCops: enable
3
- TargetRubyVersion: 3.0
3
+ TargetRubyVersion: 3.3
4
4
 
5
5
  Style/StringLiterals:
6
6
  EnforcedStyle: double_quotes
@@ -44,6 +44,9 @@ Layout/ArrayAlignment:
44
44
  Layout/LineLength:
45
45
  Enabled: false
46
46
 
47
+ Layout/LineEndStringConcatenationIndentation:
48
+ Enabled: false
49
+
47
50
  RSpec/MultipleMemoizedHelpers:
48
51
  Max: 10
49
52
 
data/CHANGELOG.md CHANGED
@@ -7,11 +7,66 @@ All notable changes to this project will be documented in this file.
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
- [unreleased]: https://github.com/dieter-medium/bidi2pdf/compare/v0.1.5..HEAD
10
+ [unreleased]: https://github.com/dieter-medium/bidi2pdf/compare/v0.1.8..HEAD
11
11
 
12
12
  <!-- generated by git-cliff end -->
13
13
 
14
- ## [0.1.6]
14
+ ## [0.1.8] - 2025-04-22
15
+
16
+ ### 🎨 Refactored
17
+
18
+ - Modularize ChromedriverContainer implementation by @dieter-medium
19
+ - Replace method calls for clarity and consistency by @dieter-medium
20
+ - Namespace PDFTextSanitizer under Bidi2pdf::TestHelpers by @dieter-medium
21
+ - Refactor command management with concurrent queues by @dieter-medium
22
+
23
+ ### 🐛 Fixed
24
+
25
+ - Update CHANGELOG links to correct Markdown syntax by @dieter-medium
26
+
27
+ ### 📝 Docs
28
+
29
+ - Add Rails integration section to README by @dieter-medium
30
+
31
+ ### 🚀 Added
32
+
33
+ - Update Chromedriver container setup and default image by @dieter-medium
34
+ - Add workflow for pushing Chromedriver Docker image by @dieter-medium
35
+ - Return session status and add test coverage by @dieter-medium
36
+ - Integrate concurrent-ruby for thread safety improvements by @dieter-medium
37
+ - Add specific navigation error classes for better handling by @dieter-medium
38
+ - Enhance navigation error handling in BrowserTab by @dieter-medium
39
+ - Add test helpers and matchers for PDF validation by @dieter-medium
40
+
41
+ ## [0.1.7] - 2025-04-17
42
+
43
+ ### 🎨 Refactored
44
+
45
+ - Move notification releated classes to new folder by @dieter-medium
46
+
47
+ ### 🔄 Changed
48
+
49
+ - Refactore custom check script in wait_until_page_loaded by @dieter-medium
50
+ - Add logger support to NetworkEventConsoleFormatter by @dieter-medium
51
+ - Refactore browser console logger support for enhanced logging by @dieter-medium
52
+
53
+ ### 🚀 Added
54
+
55
+ - Add support for predefined paper formats by @dieter-medium
56
+ - Add support for websocket-native for performance boost by @dieter-medium
57
+ - Add logging for print events by @dieter-medium
58
+ - Add configurable logging and notification service by @dieter-medium
59
+ - Introduce VerboseLogger for configurable debug levels by @dieter-medium
60
+ - Instrument Bidi2pdf methods with notification service for enhanced logging by @dieter-medium
61
+ - Introduce notifications system with event instrumentation and logging compatible to rails by @dieter-medium
62
+ - Enhance ChromedriverManager with chrome_args and improve session handling by @dieter-medium
63
+ - Add wait_until_page_loaded method for improved page load handling by @dieter-medium
64
+ - Enhance Chromedriver process management with platform-specific options by @dieter-medium
65
+ - Implement BrowserRemoveUserContext command and enhance user context cleanup by @dieter-medium
66
+ - Add style injection functionality to BrowserTab class by @dieter-medium
67
+ - Add script injection functionality to BrowserTab class by @dieter-medium
68
+
69
+ ## [0.1.6] - 2025-04-12
15
70
 
16
71
  ### ⚠️ Breaking Changes
17
72
 
@@ -117,10 +172,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
117
172
 
118
173
  - Initial release
119
174
 
120
- [unreleased]: https://github.com/dieter-medium/bidi2pdf/compare/v0.1.6..HEAD
121
-
122
- [0.1.6]: https://github.com/dieter-medium/bidi2pdf/compare/v0.1.5..v0.1.6
123
-
124
- [0.1.5]: https://github.com/dieter-medium/bidi2pdf/compare/v0.1.4..v0.1.5
125
175
 
126
- [0.1.4]: https://github.com/dieter-medium/bidi2pdf/compare/v0.1.3..v0.1.4
176
+ - [unreleased](https://github.com/dieter-medium/bidi2pdf/compare/v0.1.8..HEAD)
177
+ - [0.1.8](https://github.com/dieter-medium/bidi2pdf/compare/v0.1.7..v0.1.8)
178
+ - [0.1.7](https://github.com/dieter-medium/bidi2pdf/compare/v0.1.6..v0.1.7)
179
+ - [0.1.6](https://github.com/dieter-medium/bidi2pdf/compare/v0.1.5..v0.1.6)
180
+ - [0.1.5](https://github.com/dieter-medium/bidi2pdf/compare/v0.1.4..v0.1.5)
181
+ - [0.1.4](https://github.com/dieter-medium/bidi2pdf/compare/v0.1.3..v0.1.4)
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
  [![Maintainability](https://api.codeclimate.com/v1/badges/6425d9893aa3a9ca243e/maintainability)](https://codeclimate.com/github/dieter-medium/bidi2pdf/maintainability)
3
3
  [![Gem Version](https://badge.fury.io/rb/bidi2pdf.svg)](https://badge.fury.io/rb/bidi2pdf)
4
4
  [![Test Coverage](https://api.codeclimate.com/v1/badges/6425d9893aa3a9ca243e/test_coverage)](https://codeclimate.com/github/dieter-medium/bidi2pdf/test_coverage)
5
+ [![Open Source Helpers](https://www.codetriage.com/dieter-medium/bidi2pdf/badges/users.svg)](https://www.codetriage.com/dieter-medium/bidi2pdf)
5
6
 
6
7
  ---
7
8
 
@@ -149,12 +150,25 @@ tab.navigate_to "https://example.com"
149
150
  # Alternative: send html code to the browser
150
151
  # tab.render_html_content("<html>...</html>")
151
152
 
153
+ # Inject JavaScript if, needed
154
+ # as an url
155
+ # tab.inject_script "https://example.com/script.js"
156
+ # or inline
157
+ # tab.inject_script "console.log('Hello from injected script!')"
158
+
159
+ # Inject CSS if needed
160
+ # as an url
161
+ # tab.inject_style url: "https://example.com/simple.css"
162
+ # or inline
163
+ # tab.inject_style content: "body { background-color: red; }"
164
+
152
165
  tab.wait_until_network_idle
153
166
  tab.print("my.pdf")
154
167
 
155
168
  # 5. Cleanup
156
169
  tab.close
157
170
  window.close
171
+ context.close
158
172
  session.close
159
173
  ```
160
174
 
@@ -243,6 +257,20 @@ docker compose -f docker/docker-compose.yml down
243
257
 
244
258
  ---
245
259
 
260
+ ## 🚂 Rails Integration
261
+
262
+ Rails integration is available as an additional gem:
263
+
264
+ ```ruby
265
+ # In your Gemfile
266
+ gem 'bidi2pdf-rails'
267
+ ```
268
+
269
+ For full documentation and usage examples,
270
+ visit: [https://github.com/dieter-medium/bidi2pdf-rails](https://github.com/dieter-medium/bidi2pdf-rails)
271
+
272
+ ---
273
+
246
274
  ## 🛠 Development
247
275
 
248
276
  ```bash
data/docker/Dockerfile CHANGED
@@ -3,7 +3,7 @@ FROM ruby:3.3
3
3
  ENV DEBIAN_FRONTEND=noninteractive
4
4
 
5
5
  # Install dependencies
6
- RUN apt-get update && apt-get upgrade &&\
6
+ RUN apt-get update && apt-get upgrade -y &&\
7
7
  apt-get install -y --no-install-recommends\
8
8
  chromium chromium-driver\
9
9
  libglib2.0-0 \
@@ -5,9 +5,9 @@ ARG CHROMEDRIVER_PORT=3000
5
5
  ENV DEBIAN_FRONTEND=noninteractive
6
6
 
7
7
  # Install dependencies
8
- RUN apt-get update && apt-get upgrade && \
8
+ RUN apt-get update && apt-get upgrade -y && \
9
9
  apt-get install -y --no-install-recommends\
10
- chromium \
10
+ chromium chromium-driver\
11
11
  libglib2.0-0 \
12
12
  libnss3 \
13
13
  libxss1 \
@@ -26,6 +26,13 @@ RUN groupadd -r appuser && useradd -r -g appuser -m -d /home/appuser appuser
26
26
  COPY ./docker/entrypoint.sh /usr/local/bin/entrypoint.sh
27
27
  RUN chmod +x /usr/local/bin/entrypoint.sh
28
28
 
29
+ # ARM compatibility workaround:
30
+ # On ARM architectures (such as Apple Silicon), downloading chromedriver via automated scripts may fail or cause ELF binary errors,
31
+ # such as "rosetta error: failed to open elf at /lib64/ld-linux-x86-64.so.2".
32
+ # To avoid these issues, we directly install 'chromium-driver' via the package manager and explicitly create a symlink in the expected location.
33
+
34
+ RUN mkdir -p /home/appuser/.webdrivers && ln -s /usr/bin/chromedriver /home/appuser/.webdrivers/chromedriver
35
+
29
36
  # Set working directory
30
37
  WORKDIR /app
31
38
 
@@ -3,7 +3,7 @@ FROM ruby:3.3-slim AS builder
3
3
  ENV DEBIAN_FRONTEND=noninteractive
4
4
 
5
5
  # Install dependencies
6
- RUN apt-get update && apt-get upgrade && \
6
+ RUN apt-get update && apt-get upgrade -y && \
7
7
  apt-get install -y --no-install-recommends \
8
8
  chromium \
9
9
  libglib2.0-0 \
@@ -36,7 +36,7 @@ FROM ruby:3.3-slim
36
36
  ENV DEBIAN_FRONTEND=noninteractive
37
37
 
38
38
  # Install dependencies
39
- RUN apt-get update && apt-get upgrade &&\
39
+ RUN apt-get update && apt-get upgrade -y &&\
40
40
  apt-get install -y --no-install-recommends\
41
41
  chromium chromium-driver\
42
42
  libglib2.0-0 \
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "js_logger_helper"
4
+
5
+ module Bidi2pdf
6
+ module Bidi
7
+ class BrowserConsoleLoggerSuggar
8
+ attr_reader :browser_console_logger
9
+
10
+ def initialize(browser_console_logger)
11
+ @browser_console_logger = browser_console_logger
12
+ end
13
+
14
+ def with_level(level)
15
+ @level = level
16
+ self
17
+ end
18
+
19
+ def with_prefix(prefix)
20
+ @prefix = prefix
21
+ self
22
+ end
23
+
24
+ def with_timestamp(timestamp)
25
+ @timestamp = timestamp
26
+ self
27
+ end
28
+
29
+ def with_text(text)
30
+ @text = text
31
+ self
32
+ end
33
+
34
+ def with_args(args)
35
+ @args = args
36
+ self
37
+ end
38
+
39
+ def with_stack_trace(stack_trace)
40
+ @stack_trace = stack_trace
41
+ self
42
+ end
43
+
44
+ def log_event
45
+ browser_console_logger.log_message(@level, @prefix, @text)
46
+ browser_console_logger.log_args(@prefix, @args)
47
+ browser_console_logger.log_stack_trace(@prefix, @stack_trace) if @stack_trace && @level == :error
48
+ end
49
+
50
+ def prefix
51
+ @prefix ||= "[#{BrowserConsoleLogger.format_timestamp(@timestamp)}][Browser Console Log]"
52
+ end
53
+ end
54
+
55
+ class BrowserConsoleLogger
56
+ include JsLoggerHelper
57
+
58
+ attr_accessor :logger
59
+
60
+ def initialize(logger)
61
+ @logger = logger
62
+ end
63
+
64
+ def builder
65
+ BrowserConsoleLoggerSuggar.new(self)
66
+ end
67
+
68
+ def log_message(level, prefix, text)
69
+ return unless text
70
+
71
+ logger.send(level, "#{prefix} #{text}")
72
+ end
73
+
74
+ def log_args(prefix, args)
75
+ return if args.empty?
76
+
77
+ logger.debug("#{prefix} Args: #{args.inspect}")
78
+ end
79
+
80
+ def log_stack_trace(prefix, trace)
81
+ formatted_trace = format_stack_trace(trace)
82
+ logger.error("#{prefix} Stack trace captured:\n#{formatted_trace}")
83
+ end
84
+
85
+ def self.format_timestamp(timestamp)
86
+ return "N/A" unless timestamp
87
+
88
+ Time.at(timestamp.to_f / 1000).utc.strftime("%Y-%m-%d %H:%M:%S.%L UTC")
89
+ end
90
+ end
91
+ end
92
+ end