bidi2pdf 0.1.12 → 0.1.14
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 +4 -4
- data/.devcontainer/Dockerfile +53 -0
- data/.devcontainer/devcontainer.json +51 -0
- data/.devcontainer/docker-compose.yml +33 -0
- data/.rubocop.yml +1 -1
- data/.ruby-gemset +1 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +115 -4
- data/README.md +12 -0
- data/docker/Dockerfile +2 -2
- data/docker/Dockerfile.slim +2 -2
- data/docker/chrome-driver/chrome.json +874 -0
- data/docker/entrypoint.sh +3 -3
- data/lib/bidi2pdf/bidi/browser_tab.rb +52 -0
- data/lib/bidi2pdf/bidi/commands/capture_screenshot.rb +33 -0
- data/lib/bidi2pdf/bidi/commands/set_viewport.rb +32 -0
- data/lib/bidi2pdf/bidi/commands.rb +2 -0
- data/lib/bidi2pdf/bidi/event_manager.rb +2 -2
- data/lib/bidi2pdf/chromedriver_manager.rb +11 -0
- data/lib/bidi2pdf/cli.rb +11 -1
- data/lib/bidi2pdf/launcher.rb +5 -3
- data/lib/bidi2pdf/process_tree.rb +2 -2
- data/lib/bidi2pdf/test_helpers/images.rb +8 -0
- data/lib/bidi2pdf/test_helpers/pdf_file_helper.rb +5 -1
- data/lib/bidi2pdf/test_helpers/pdf_reader_utils.rb +1 -2
- data/lib/bidi2pdf/test_helpers/pdf_text_sanitizer.rb +29 -109
- data/lib/bidi2pdf/test_helpers/testcontainers/chromedriver_container.rb +1 -1
- data/lib/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rb +46 -13
- data/lib/bidi2pdf/test_helpers/testcontainers/container_endpoint.rb +30 -0
- data/lib/bidi2pdf/test_helpers/testcontainers/shared_docker_network.rb +5 -1
- data/lib/bidi2pdf/test_helpers/testcontainers/testcontainers_refinement.rb +33 -0
- data/lib/bidi2pdf/test_helpers/testcontainers.rb +1 -0
- data/lib/bidi2pdf/version.rb +1 -1
- data/lib/bidi2pdf.rb +2 -0
- data/sig/bidi2pdf/bidi/add_headers_interceptor.rbs +16 -9
- data/sig/bidi2pdf/bidi/auth_interceptor.rbs +32 -7
- data/sig/bidi2pdf/bidi/browser.rbs +4 -31
- data/sig/bidi2pdf/bidi/browser_console_logger.rbs +59 -0
- data/sig/bidi2pdf/bidi/browser_tab.rbs +252 -25
- data/sig/bidi2pdf/bidi/client.rbs +95 -43
- data/sig/bidi2pdf/bidi/command_manager.rbs +5 -17
- data/sig/bidi2pdf/bidi/commands/add_intercept.rbs +16 -8
- data/sig/bidi2pdf/bidi/commands/base.rbs +49 -9
- data/sig/bidi2pdf/bidi/commands/browser_close.rbs +3 -1
- data/sig/bidi2pdf/bidi/commands/browser_create_user_context.rbs +2 -0
- data/sig/bidi2pdf/bidi/commands/browser_remove_user_context.rbs +19 -0
- data/sig/bidi2pdf/bidi/commands/browsing_context_close.rbs +8 -2
- data/sig/bidi2pdf/bidi/commands/browsing_context_navigate.rbs +12 -6
- data/sig/bidi2pdf/bidi/commands/browsing_context_print.rbs +10 -5
- data/sig/bidi2pdf/bidi/commands/cancel_auth.rbs +8 -2
- data/sig/bidi2pdf/bidi/commands/capture_screenshot.rbs +31 -0
- data/sig/bidi2pdf/bidi/commands/cdp_get_session.rbs +17 -0
- data/sig/bidi2pdf/bidi/commands/create_window.rbs +4 -0
- data/sig/bidi2pdf/bidi/commands/get_user_contexts.rbs +2 -0
- data/sig/bidi2pdf/bidi/commands/network_continue.rbs +4 -0
- data/sig/bidi2pdf/bidi/commands/page_print.rbs +28 -0
- data/sig/bidi2pdf/bidi/commands/print_parameters_validator.rbs +3 -0
- data/sig/bidi2pdf/bidi/commands/provide_credentials.rbs +12 -6
- data/sig/bidi2pdf/bidi/commands/script_evaluate.rbs +4 -0
- data/sig/bidi2pdf/bidi/commands/session_end.rbs +2 -0
- data/sig/bidi2pdf/bidi/commands/session_status.rbs +3 -1
- data/sig/bidi2pdf/bidi/commands/session_subscribe.rbs +4 -0
- data/sig/bidi2pdf/bidi/commands/set_tab_cookie.rbs +51 -23
- data/sig/bidi2pdf/bidi/commands/set_usercontext_cookie.rbs +17 -19
- data/sig/bidi2pdf/bidi/commands/set_viewport.rbs +31 -0
- data/sig/bidi2pdf/bidi/connection_manager.rbs +2 -1
- data/sig/bidi2pdf/bidi/event_manager.rbs +14 -19
- data/sig/bidi2pdf/bidi/interceptor.rbs +5 -0
- data/sig/bidi2pdf/bidi/js_logger_helper.rbs +9 -0
- data/sig/bidi2pdf/bidi/logger_events.rbs +21 -0
- data/sig/bidi2pdf/bidi/navigation_failed_events.rbs +17 -0
- data/sig/bidi2pdf/bidi/network_event.rbs +54 -46
- data/sig/bidi2pdf/bidi/network_event_formatters/network_event_console_formatter.rbs +63 -0
- data/sig/bidi2pdf/bidi/network_event_formatters/network_event_formatter_utils.rbs +15 -0
- data/sig/bidi2pdf/bidi/network_event_formatters/network_event_html_formatter.rbs +18 -0
- data/sig/bidi2pdf/bidi/network_event_formatters.rbs +6 -0
- data/sig/bidi2pdf/bidi/network_events.rbs +14 -39
- data/sig/bidi2pdf/bidi/session.rbs +144 -31
- data/sig/bidi2pdf/bidi/user_context.rbs +64 -45
- data/sig/bidi2pdf/bidi/web_socket_dispatcher.rbs +22 -30
- data/sig/bidi2pdf/chromedriver_manager.rbs +57 -22
- data/sig/bidi2pdf/cli.rbs +22 -2
- data/sig/bidi2pdf/dsl.rbs +34 -0
- data/sig/bidi2pdf/launcher.rbs +39 -1
- data/sig/bidi2pdf/notifications/event.rbs +40 -0
- data/sig/bidi2pdf/notifications/instrumenter.rbs +21 -0
- data/sig/bidi2pdf/notifications/logging_subscriber.rbs +41 -0
- data/sig/bidi2pdf/notifications.rbs +24 -0
- data/sig/bidi2pdf/process_tree.rbs +2 -2
- data/sig/bidi2pdf/session_runner.rbs +41 -1
- data/sig/bidi2pdf/test_helpers/configuration.rbs +51 -0
- data/sig/bidi2pdf/test_helpers/images/extractor.rbs +43 -0
- data/sig/bidi2pdf/test_helpers/images/image_similarity_checker.rbs +35 -0
- data/sig/bidi2pdf/test_helpers/images/tiff_helper.rbs +70 -0
- data/sig/bidi2pdf/test_helpers/images.rbs +0 -0
- data/sig/bidi2pdf/test_helpers/matchers/contains_pdf_image.rbs +0 -0
- data/sig/bidi2pdf/test_helpers/matchers/contains_pdf_text.rbs +0 -0
- data/sig/bidi2pdf/test_helpers/matchers/have_pdf_page_count.rbs +0 -0
- data/sig/bidi2pdf/test_helpers/matchers/match_pdf_text.rbs +0 -0
- data/sig/bidi2pdf/test_helpers/pdf_file_helper.rbs +23 -0
- data/sig/bidi2pdf/test_helpers/pdf_reader_utils.rbs +49 -0
- data/sig/bidi2pdf/test_helpers/pdf_text_sanitizer.rbs +38 -0
- data/sig/bidi2pdf/test_helpers/spec_paths_helper.rbs +35 -0
- data/sig/bidi2pdf/test_helpers/testcontainers/chromedriver_container.rbs +43 -0
- data/sig/bidi2pdf/test_helpers/testcontainers/chromedriver_test_helper.rbs +45 -0
- data/sig/bidi2pdf/test_helpers/testcontainers/container_endpoint.rbs +25 -0
- data/sig/bidi2pdf/test_helpers/testcontainers/shared_docker_network.rbs +3 -0
- data/sig/bidi2pdf/test_helpers/testcontainers/testcontainers_refinement.rbs +47 -0
- data/sig/bidi2pdf/test_helpers/testcontainers.rbs +6 -0
- data/sig/bidi2pdf/test_helpers.rbs +0 -0
- data/sig/bidi2pdf/verbose_logger.rbs +37 -0
- data/sig/bidi2pdf/version.rbs +3 -0
- data/sig/bidi2pdf.rbs +112 -2
- data/tasks/generate_rbs.rake +11 -11
- metadata +62 -10
- data/sig/bidi2pdf/utils.rbs +0 -5
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
# rubocop: disable Lint/RescueException, Lint/SuppressedException
|
|
3
|
+
module Notifications
|
|
4
|
+
class Instrumenter
|
|
5
|
+
@id: untyped
|
|
6
|
+
|
|
7
|
+
attr_reader id: untyped
|
|
8
|
+
|
|
9
|
+
def initialize: () -> void
|
|
10
|
+
|
|
11
|
+
def notify: (untyped name, untyped payload) { (?) -> untyped } -> untyped
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def create_event: (untyped name, untyped payload) -> untyped
|
|
16
|
+
|
|
17
|
+
# rubocop:disable Style/CaseEquality
|
|
18
|
+
def notify_subscribers: (untyped name, untyped event) -> untyped
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module Notifications
|
|
3
|
+
# for reuse within ActiveSupport::LogSubscriber
|
|
4
|
+
module LoggingSubscriberActions
|
|
5
|
+
def handle_response: (untyped event) -> untyped
|
|
6
|
+
|
|
7
|
+
def send_cmd: (untyped event) -> untyped
|
|
8
|
+
|
|
9
|
+
def send_cmd_and_wait: (untyped event) -> (nil | untyped)
|
|
10
|
+
|
|
11
|
+
def session_close: (untyped event) -> (nil | untyped)
|
|
12
|
+
|
|
13
|
+
# rubocop: disable Metrics/AbcSize
|
|
14
|
+
def network_event_received: (untyped event) -> (nil | untyped)
|
|
15
|
+
|
|
16
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
17
|
+
def network_idle: (untyped event) -> (nil | untyped)
|
|
18
|
+
|
|
19
|
+
def page_loaded: (untyped event) -> untyped
|
|
20
|
+
|
|
21
|
+
def print: (untyped event) -> untyped
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def redact_sensitive_fields: (untyped obj, ?::Array[untyped] sensitive_keys) -> untyped
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class LoggingSubscriber
|
|
29
|
+
@logger: untyped
|
|
30
|
+
|
|
31
|
+
include LoggingSubscriberActions
|
|
32
|
+
|
|
33
|
+
attr_accessor logger: untyped
|
|
34
|
+
|
|
35
|
+
# rubocop: disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
36
|
+
def initialize: (?logger: untyped) -> void
|
|
37
|
+
|
|
38
|
+
def unsubscribe: () -> untyped
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module Notifications
|
|
3
|
+
self.@subscribers: untyped
|
|
4
|
+
|
|
5
|
+
attr_reader self.subscribers: untyped
|
|
6
|
+
|
|
7
|
+
def self.instrument: (untyped name, ?::Hash[untyped, untyped] payload) ?{ (untyped) -> untyped } -> untyped
|
|
8
|
+
|
|
9
|
+
def self.subscribe: (untyped event_pattern) { (?) -> untyped } -> untyped
|
|
10
|
+
|
|
11
|
+
def self.unsubscribe: (untyped event_pattern, ?untyped? block) -> untyped
|
|
12
|
+
|
|
13
|
+
# rubocop: disable Style/CaseEquality
|
|
14
|
+
def self.listening?: (untyped name) -> untyped
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def self.bidi2pdf_notification_instrumenter: () -> untyped
|
|
19
|
+
|
|
20
|
+
def self.notify: (untyped name, untyped payload) { (?) -> untyped } -> untyped
|
|
21
|
+
|
|
22
|
+
def self.normalize_pattern: (untyped pat) -> untyped
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -10,7 +10,7 @@ module Bidi2pdf
|
|
|
10
10
|
|
|
11
11
|
def children: (untyped of_pid) -> (::Array[untyped] | untyped)
|
|
12
12
|
|
|
13
|
-
def traverse: () { () -> untyped } -> untyped
|
|
13
|
+
def traverse: () { (?) -> untyped } -> untyped
|
|
14
14
|
|
|
15
15
|
private
|
|
16
16
|
|
|
@@ -22,6 +22,6 @@ module Bidi2pdf
|
|
|
22
22
|
|
|
23
23
|
def root_pids: () -> (::Array[untyped] | untyped)
|
|
24
24
|
|
|
25
|
-
def traverse_branch: (untyped pid, ?::Integer level) { () -> untyped } -> (nil | untyped)
|
|
25
|
+
def traverse_branch: (untyped pid, ?::Integer level) { (?) -> untyped } -> (nil | untyped)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -1,9 +1,43 @@
|
|
|
1
1
|
module Bidi2pdf
|
|
2
|
+
# Represents a runner for managing browser sessions and executing tasks
|
|
3
|
+
# using the Bidi2pdf library. This class handles the setup, configuration,
|
|
4
|
+
# and execution of browser-related workflows, including navigation, cookie
|
|
5
|
+
# management, and printing.
|
|
6
|
+
#
|
|
7
|
+
# @example Running a session
|
|
8
|
+
# session_runner = Bidi2pdf::SessionRunner.new(
|
|
9
|
+
# session: session,
|
|
10
|
+
# url: "http://example.com",
|
|
11
|
+
# inputfile: "input.html",
|
|
12
|
+
# output: "output.pdf",
|
|
13
|
+
# cookies: { "key" => "value" },
|
|
14
|
+
# headers: { "Authorization" => "Bearer token" },
|
|
15
|
+
# auth: { username: "user", password: "pass" },
|
|
16
|
+
# wait_window_loaded: true,
|
|
17
|
+
# wait_network_idle: true,
|
|
18
|
+
# print_options: { landscape: true },
|
|
19
|
+
# network_log_format: :json
|
|
20
|
+
# )
|
|
21
|
+
# session_runner.run
|
|
22
|
+
#
|
|
23
|
+
# @param [Object] session The browser session object to use.
|
|
24
|
+
# @param [String, nil] url The URL to navigate to in the browser session.
|
|
25
|
+
# @param [String, nil] inputfile The path to the input file to be processed if no URL is provided.
|
|
26
|
+
# @param [String, nil] output The path to the output file to be generated.
|
|
27
|
+
# @param [Hash] cookies A hash of cookies to set in the browser session. Defaults to an empty hash.
|
|
28
|
+
# @param [Hash] headers A hash of HTTP headers to include in the browser session. Defaults to an empty hash.
|
|
29
|
+
# @param [Hash, nil] auth Authentication credentials (e.g., username and password). Defaults to an empty hash.
|
|
30
|
+
# @param [Boolean] wait_window_loaded Whether to wait for the window to fully load. Defaults to false.
|
|
31
|
+
# @param [Boolean] wait_network_idle Whether to wait for the network to become idle. Defaults to false.
|
|
32
|
+
# @param [Hash] print_options Options for printing the page. Defaults to an empty hash.
|
|
33
|
+
# @param [Symbol] network_log_format The format for network logs. Defaults to :console.
|
|
2
34
|
class SessionRunner
|
|
3
35
|
@session: untyped
|
|
4
36
|
|
|
5
37
|
@url: untyped
|
|
6
38
|
|
|
39
|
+
@inputfile: untyped
|
|
40
|
+
|
|
7
41
|
@output: untyped
|
|
8
42
|
|
|
9
43
|
@cookies: untyped
|
|
@@ -18,13 +52,18 @@ module Bidi2pdf
|
|
|
18
52
|
|
|
19
53
|
@print_options: untyped
|
|
20
54
|
|
|
55
|
+
@network_log_format: untyped
|
|
56
|
+
|
|
21
57
|
@window: untyped
|
|
22
58
|
|
|
23
59
|
@tab: untyped
|
|
24
60
|
|
|
61
|
+
@user_context: untyped
|
|
62
|
+
|
|
25
63
|
@uri: untyped
|
|
26
64
|
|
|
27
|
-
|
|
65
|
+
# rubocop: disable Metrics/ParameterLists
|
|
66
|
+
def initialize: (session: untyped, url: untyped, inputfile: untyped, output: untyped, ?cookies: ::Hash[untyped, untyped], ?headers: ::Hash[untyped, untyped], ?auth: ::Hash[untyped, untyped], ?wait_window_loaded: bool, ?wait_network_idle: bool, ?print_options: ::Hash[untyped, untyped], ?network_log_format: ::Symbol) -> void
|
|
28
67
|
|
|
29
68
|
def run: () -> untyped
|
|
30
69
|
|
|
@@ -38,6 +77,7 @@ module Bidi2pdf
|
|
|
38
77
|
|
|
39
78
|
def add_basic_auth: () -> (nil | untyped)
|
|
40
79
|
|
|
80
|
+
# rubocop: disable Metrics/AbcSize
|
|
41
81
|
def run_flow: () -> untyped
|
|
42
82
|
|
|
43
83
|
def uri: () -> untyped
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
self.@configuration: untyped
|
|
4
|
+
|
|
5
|
+
class Configuration
|
|
6
|
+
@spec_dir: untyped
|
|
7
|
+
|
|
8
|
+
@docker_dir: untyped
|
|
9
|
+
|
|
10
|
+
@fixture_dir: untyped
|
|
11
|
+
|
|
12
|
+
@tmp_dir: untyped
|
|
13
|
+
|
|
14
|
+
@prefix: untyped
|
|
15
|
+
|
|
16
|
+
# @!attribute [rw] spec_dir
|
|
17
|
+
# @return [Pathname] the directory where specs are located
|
|
18
|
+
attr_accessor spec_dir: untyped
|
|
19
|
+
|
|
20
|
+
# @!attribute [rw] tmp_dir
|
|
21
|
+
# @return [String] the directory for temporary files
|
|
22
|
+
attr_accessor tmp_dir: untyped
|
|
23
|
+
|
|
24
|
+
# @!attribute [rw] prefix
|
|
25
|
+
# @return [String] the prefix for temporary files
|
|
26
|
+
attr_accessor prefix: untyped
|
|
27
|
+
|
|
28
|
+
# @!attribute [rw] docker_dir
|
|
29
|
+
# @return [String] the directory for Docker files
|
|
30
|
+
attr_accessor docker_dir: untyped
|
|
31
|
+
|
|
32
|
+
# @!attribute [rw] fixture_dir
|
|
33
|
+
# @return [String] the directory for fixture files
|
|
34
|
+
attr_accessor fixture_dir: untyped
|
|
35
|
+
|
|
36
|
+
def initialize: () -> void
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Retrieves the current configuration object for TestHelpers.
|
|
40
|
+
# @return [Configuration] the configuration object
|
|
41
|
+
def self.configuration: () -> untyped
|
|
42
|
+
|
|
43
|
+
# Sets the configuration object for TestHelpers.
|
|
44
|
+
# @param [Configuration] config the configuration object to set
|
|
45
|
+
attr_writer self.configuration: untyped
|
|
46
|
+
|
|
47
|
+
# Allows configuration of TestHelpers by yielding the configuration object.
|
|
48
|
+
# @yieldparam [Configuration] configuration the configuration object to modify
|
|
49
|
+
def self.configure: () { (untyped) -> untyped } -> untyped
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
module Images
|
|
4
|
+
class Extractor
|
|
5
|
+
@pages: untyped
|
|
6
|
+
|
|
7
|
+
@logger: untyped
|
|
8
|
+
|
|
9
|
+
@extracted_images: untyped
|
|
10
|
+
|
|
11
|
+
include PDFReaderUtils
|
|
12
|
+
|
|
13
|
+
include TIFFHelper
|
|
14
|
+
|
|
15
|
+
attr_reader pages: untyped
|
|
16
|
+
|
|
17
|
+
attr_reader logger: untyped
|
|
18
|
+
|
|
19
|
+
def initialize: (untyped pdf_data, ?logger: untyped) -> void
|
|
20
|
+
|
|
21
|
+
def all_images: () -> untyped
|
|
22
|
+
|
|
23
|
+
def image_on_page: (untyped page_number, untyped image_number) -> (nil | untyped)
|
|
24
|
+
|
|
25
|
+
def images_on_page: (untyped page_number) -> untyped
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def extracted_images: () -> untyped
|
|
30
|
+
|
|
31
|
+
def extract_images: (untyped page) -> (nil | untyped)
|
|
32
|
+
|
|
33
|
+
def process_image_stream: (untyped stream) -> (nil | untyped)
|
|
34
|
+
|
|
35
|
+
def extract_raw_image_data: (untyped stream, untyped filter) -> untyped
|
|
36
|
+
|
|
37
|
+
def handle_compressed_image: (untyped stream) -> untyped
|
|
38
|
+
|
|
39
|
+
def create_vips_image: (untyped raw, untyped filter) -> untyped
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
module Images
|
|
4
|
+
class ImageSimilarityChecker
|
|
5
|
+
@expected_image: untyped
|
|
6
|
+
|
|
7
|
+
@image_to_check: untyped
|
|
8
|
+
|
|
9
|
+
@expected_fingerprint: untyped
|
|
10
|
+
|
|
11
|
+
@actual_fingerprint: untyped
|
|
12
|
+
|
|
13
|
+
@distance: untyped
|
|
14
|
+
|
|
15
|
+
def initialize: (untyped expected_image, untyped image_to_check) -> void
|
|
16
|
+
|
|
17
|
+
def similar?: (?tolerance: ::Integer) -> untyped
|
|
18
|
+
|
|
19
|
+
def very_similar?: () -> untyped
|
|
20
|
+
|
|
21
|
+
def slightly_similar?: () -> untyped
|
|
22
|
+
|
|
23
|
+
def different?: () -> untyped
|
|
24
|
+
|
|
25
|
+
def expected_fingerprint: () -> untyped
|
|
26
|
+
|
|
27
|
+
def actual_fingerprint: () -> untyped
|
|
28
|
+
|
|
29
|
+
def distance: () -> untyped
|
|
30
|
+
|
|
31
|
+
def fingerprint: (untyped image) -> untyped
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
module Images
|
|
4
|
+
# rubocop: disable Metrics/ModuleLength, Metrics/AbcSize
|
|
5
|
+
module TIFFHelper
|
|
6
|
+
# TIFF Tag IDs
|
|
7
|
+
IMAGE_WIDTH: 256
|
|
8
|
+
|
|
9
|
+
IMAGE_LENGTH: 257
|
|
10
|
+
|
|
11
|
+
BITS_PER_SAMPLE: 258
|
|
12
|
+
|
|
13
|
+
COMPRESSION: 259
|
|
14
|
+
|
|
15
|
+
PHOTOMETRIC_INTERPRETATION: 262
|
|
16
|
+
|
|
17
|
+
STRIP_OFFSETS: 273
|
|
18
|
+
|
|
19
|
+
SAMPLES_PER_PIXEL: 277
|
|
20
|
+
|
|
21
|
+
ROWS_PER_STRIP: 278
|
|
22
|
+
|
|
23
|
+
STRIP_BYTE_COUNTS: 279
|
|
24
|
+
|
|
25
|
+
PLANAR_CONFIGURATION: 284
|
|
26
|
+
|
|
27
|
+
INK_SET: 332
|
|
28
|
+
|
|
29
|
+
# TIFF Data Types
|
|
30
|
+
TYPE_SHORT: 3
|
|
31
|
+
|
|
32
|
+
TYPE_LONG: 4
|
|
33
|
+
|
|
34
|
+
# TIFF Compression Types
|
|
35
|
+
COMPRESSION_NONE: 1
|
|
36
|
+
|
|
37
|
+
COMPRESSION_CCITT_G3: 3
|
|
38
|
+
|
|
39
|
+
COMPRESSION_CCITT_G4: 4
|
|
40
|
+
|
|
41
|
+
# TIFF Photometric Interpretations
|
|
42
|
+
PHOTO_WHITE_IS_ZERO: 0
|
|
43
|
+
|
|
44
|
+
PHOTO_BLACK_IS_ZERO: 1
|
|
45
|
+
|
|
46
|
+
PHOTO_RGB: 2
|
|
47
|
+
|
|
48
|
+
PHOTO_SEPARATION: 5
|
|
49
|
+
|
|
50
|
+
# Planar Configuration
|
|
51
|
+
PLANAR_CHUNKY: 1
|
|
52
|
+
|
|
53
|
+
def tiff_header: (untyped hash, untyped data) -> untyped
|
|
54
|
+
|
|
55
|
+
# See:
|
|
56
|
+
# * https://gist.github.com/gstorer/f6a9f1dfe41e8e64dcf58d07afa9ab2a
|
|
57
|
+
# * https://github.com/yob/pdf-reader/blob/main/examples/extract_images.rb
|
|
58
|
+
def pack_tiff: (untyped entries) -> untyped
|
|
59
|
+
|
|
60
|
+
def tiff_header_for_gray: (untyped hash, untyped data) -> untyped
|
|
61
|
+
|
|
62
|
+
def tiff_header_for_ccitt: (untyped hash, untyped data) -> untyped
|
|
63
|
+
|
|
64
|
+
def tiff_header_for_cmyk: (untyped hash, untyped data) -> untyped
|
|
65
|
+
|
|
66
|
+
def tiff_header_for_rgb: (untyped hash, untyped data) -> untyped
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
# This module provides helper methods for handling PDF files in tests.
|
|
4
|
+
# It includes methods for debugging, storing, and managing PDF files.
|
|
5
|
+
module PdfFileHelper
|
|
6
|
+
def reporter: () -> untyped
|
|
7
|
+
|
|
8
|
+
# Executes a block with the given PDF data and handles debugging in case of test failures.
|
|
9
|
+
# If an expectation fails, the PDF data is saved to a file for debugging purposes.
|
|
10
|
+
# @param [String] pdf_data the PDF data to debug
|
|
11
|
+
# @yield [String] yields the PDF data to the given block
|
|
12
|
+
# @raise [RSpec::Expectations::ExpectationNotMetError] re-raises the exception after saving the PDF
|
|
13
|
+
def with_pdf_debug: (untyped pdf_data) { (untyped) -> untyped } -> untyped
|
|
14
|
+
|
|
15
|
+
# Stores the given PDF data to a file with a specified filename prefix.
|
|
16
|
+
# The file is saved in a temporary directory.
|
|
17
|
+
# @param [String] pdf_data the PDF data to store
|
|
18
|
+
# @param [String] filename_prefix the prefix for the generated filename (default: "test")
|
|
19
|
+
# @return [String] the full path to the saved PDF file
|
|
20
|
+
def store_pdf_file: (untyped pdf_data, ?::String filename_prefix) -> untyped
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
module PDFReaderUtils
|
|
4
|
+
# Extracts text content from a PDF document.
|
|
5
|
+
#
|
|
6
|
+
# This method accepts various PDF input formats and attempts to extract text content
|
|
7
|
+
# from all pages. If extraction fails due to malformed PDF data, it returns the original input.
|
|
8
|
+
#
|
|
9
|
+
# @param pdf_data [String, StringIO, File] The PDF data in one of the following formats:
|
|
10
|
+
# * Base64-encoded PDF string
|
|
11
|
+
# * Raw PDF data beginning with "%PDF-"
|
|
12
|
+
# * StringIO object containing PDF data
|
|
13
|
+
# * Path to a PDF file as String
|
|
14
|
+
# * Raw PDF data as String
|
|
15
|
+
# @return [Array<String>] An array of strings, with each string representing the text content of a page
|
|
16
|
+
# @return [Object] The original input if PDF extraction fails
|
|
17
|
+
# @example Extract text from a PDF file
|
|
18
|
+
# text_content = pdf_text('path/to/document.pdf')
|
|
19
|
+
#
|
|
20
|
+
# @example Extract text from Base64-encoded string
|
|
21
|
+
# text_content = pdf_text(base64_encoded_pdf_data)
|
|
22
|
+
def self.pdf_text: (untyped pdf_data) -> untyped
|
|
23
|
+
|
|
24
|
+
# Converts the input PDF data into an IO object and initializes a PDF::Reader.
|
|
25
|
+
#
|
|
26
|
+
# @param pdf_data [String, StringIO, File] The PDF data to be read.
|
|
27
|
+
# @return [PDF::Reader] A PDF::Reader instance for the given data.
|
|
28
|
+
# @raise [PDF::Reader::MalformedPDFError] If the PDF data is invalid.
|
|
29
|
+
def self.pdf_reader_for: (untyped pdf_data) -> untyped
|
|
30
|
+
|
|
31
|
+
# rubocop: disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
32
|
+
# Converts various input formats into an IO object for PDF::Reader.
|
|
33
|
+
#
|
|
34
|
+
# @param pdf_data [String, StringIO, File] The PDF data to be converted.
|
|
35
|
+
# @return [IO] An IO object containing the PDF data.
|
|
36
|
+
def self.convert_data_to_io: (untyped pdf_data) -> untyped
|
|
37
|
+
|
|
38
|
+
module InstanceMethods
|
|
39
|
+
def pdf_text: (untyped pdf_data) -> untyped
|
|
40
|
+
|
|
41
|
+
def pdf_reader_for: (untyped pdf_data) -> untyped
|
|
42
|
+
|
|
43
|
+
def convert_data_to_io: (untyped pdf_data) -> untyped
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.included: (untyped base) -> untyped
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
# rubocop: disable-next Metrics/ModuleLength
|
|
4
|
+
module PDFTextSanitizer
|
|
5
|
+
def self.clean: (untyped text) -> untyped
|
|
6
|
+
|
|
7
|
+
def self.clean_pages: (untyped pdf) -> untyped
|
|
8
|
+
|
|
9
|
+
def self.normalize: (untyped text) -> untyped
|
|
10
|
+
|
|
11
|
+
def self.contains?: (untyped actual_pdf_thingy, untyped expected, ?untyped? page_number) -> (false | untyped)
|
|
12
|
+
|
|
13
|
+
def self.match_expected?: (untyped text, untyped expected) -> (false | untyped)
|
|
14
|
+
|
|
15
|
+
def self.match?: (untyped actual_pdf_thingy, untyped expected_pdf_thingy) -> (true | false)
|
|
16
|
+
|
|
17
|
+
def self.report_content_mismatch: (untyped actual, untyped expected) -> untyped
|
|
18
|
+
|
|
19
|
+
def self.content_mismatch_message: (untyped actual, untyped expected) -> untyped
|
|
20
|
+
|
|
21
|
+
def self.page_difference_message: (untyped actual_page, untyped expected_page, untyped page_idx) -> (nil | untyped)
|
|
22
|
+
|
|
23
|
+
def self.format_diff_output: (untyped diffs, untyped expected, untyped actual) -> untyped
|
|
24
|
+
|
|
25
|
+
def self.reporter: () -> untyped
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def self.group_changed_diffs: (untyped diffs) -> untyped
|
|
30
|
+
|
|
31
|
+
def self.format_change: (untyped expected, untyped actual, untyped change) -> untyped
|
|
32
|
+
|
|
33
|
+
def self.extract_snippets: (untyped expected, untyped actual, untyped change, untyped pos) -> { context_start: untyped, context: untyped, expected_snip: untyped, actual_snip: untyped }
|
|
34
|
+
|
|
35
|
+
def self.build_output: (untyped snip_data, untyped pos) -> ::Array[::String]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# This module provides helper methods for managing paths in test environments.
|
|
2
|
+
# It includes methods to retrieve directories and generate temporary file paths.
|
|
3
|
+
module Bidi2pdf
|
|
4
|
+
module TestHelpers
|
|
5
|
+
# This submodule contains path-related helper methods and configuration for tests.
|
|
6
|
+
module SpecPathsHelper
|
|
7
|
+
# Retrieves the directory path for Docker files.
|
|
8
|
+
# @return [String] the Docker directory path
|
|
9
|
+
def fixture_dir: () -> untyped
|
|
10
|
+
|
|
11
|
+
# Retrieves the directory path for fixtures.
|
|
12
|
+
# @return [String] the fixture directory path
|
|
13
|
+
def fixture_file: (*untyped) -> untyped
|
|
14
|
+
|
|
15
|
+
# Retrieves the directory path for specs.
|
|
16
|
+
# @return [String] the spec directory path
|
|
17
|
+
def spec_dir: () -> untyped
|
|
18
|
+
|
|
19
|
+
# Retrieves the directory path for temporary files.
|
|
20
|
+
# @return [String] the temporary directory path
|
|
21
|
+
def tmp_dir: () -> untyped
|
|
22
|
+
|
|
23
|
+
# Generates a path for a temporary file by joining the temporary directory with the given parts.
|
|
24
|
+
# @param [Array<String>] parts the parts of the file path to join
|
|
25
|
+
# @return [String] the full path to the temporary file
|
|
26
|
+
def tmp_file: (*untyped parts) -> untyped
|
|
27
|
+
|
|
28
|
+
# Generates a random temporary directory path.
|
|
29
|
+
# @param [Array<String>] dirs additional directory components to include in the path
|
|
30
|
+
# @param [String, nil] prefix an optional prefix for the directory name
|
|
31
|
+
# @return [String] the full path to the random temporary directory
|
|
32
|
+
def random_tmp_dir: (*untyped dirs, ?prefix: untyped?) -> untyped
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
module Testcontainers
|
|
4
|
+
class ChromedriverContainer < ::Testcontainers::DockerContainer
|
|
5
|
+
@docker_file: untyped
|
|
6
|
+
|
|
7
|
+
@build_dir: untyped
|
|
8
|
+
|
|
9
|
+
@wait_for: untyped
|
|
10
|
+
|
|
11
|
+
@_container: untyped
|
|
12
|
+
|
|
13
|
+
@_id: untyped
|
|
14
|
+
|
|
15
|
+
@name: untyped
|
|
16
|
+
|
|
17
|
+
@_created_at: untyped
|
|
18
|
+
|
|
19
|
+
DEFAULT_CHROMEDRIVER_PORT: 3000
|
|
20
|
+
|
|
21
|
+
DEFAULT_IMAGE: "dieters877565/chromedriver"
|
|
22
|
+
|
|
23
|
+
attr_reader docker_file: untyped
|
|
24
|
+
|
|
25
|
+
attr_reader build_dir: untyped
|
|
26
|
+
|
|
27
|
+
def initialize: (?untyped image, **untyped options) -> void
|
|
28
|
+
|
|
29
|
+
def start: () -> untyped
|
|
30
|
+
|
|
31
|
+
def port: () -> untyped
|
|
32
|
+
|
|
33
|
+
# rubocop: disable Metrics/AbcSize
|
|
34
|
+
def build_local_image: () -> untyped
|
|
35
|
+
|
|
36
|
+
# rubocop: disable Metrics/AbcSize
|
|
37
|
+
def start_local_image: () -> untyped
|
|
38
|
+
|
|
39
|
+
def session_url: (?protocol: ::String) -> untyped
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
module Testcontainers
|
|
4
|
+
module ChromedriverTestHelper
|
|
5
|
+
def session_url: () -> untyped
|
|
6
|
+
|
|
7
|
+
def chromedriver_container: () -> untyped
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module SessionTestHelper
|
|
11
|
+
def reporter: () -> untyped
|
|
12
|
+
|
|
13
|
+
def chrome_args: () -> untyped
|
|
14
|
+
|
|
15
|
+
def create_session: (untyped session_url) -> untyped
|
|
16
|
+
|
|
17
|
+
# Full session/tab lifecycle in one call - create_session above only builds the session
|
|
18
|
+
# object, it never starts or closes it, and there is no after(:each) teardown for a spec
|
|
19
|
+
# that uses it directly. Mirrors Bidi2pdf::DSL.with_tab's own ensure-based teardown, but
|
|
20
|
+
# against a session_url this module already knows about (a long-lived remote-chrome
|
|
21
|
+
# reached over `session:` metadata, not a freshly spawned local chromedriver per call).
|
|
22
|
+
def with_tab: (untyped session_url) { (untyped) -> untyped } -> untyped
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# alias the long class name
|
|
29
|
+
ChromedriverTestcontainer: untyped
|
|
30
|
+
|
|
31
|
+
class Object
|
|
32
|
+
def stop_container: (untyped container) -> (nil | untyped)
|
|
33
|
+
|
|
34
|
+
def dump_container_logs: (untyped container) -> (nil | untyped)
|
|
35
|
+
|
|
36
|
+
def stop_running_container: (untyped container) -> (nil | untyped)
|
|
37
|
+
|
|
38
|
+
def reporter: () -> untyped
|
|
39
|
+
|
|
40
|
+
def chromedriver_tests_present?: () -> untyped
|
|
41
|
+
|
|
42
|
+
def test_of_kind_present?: (untyped type) -> untyped
|
|
43
|
+
|
|
44
|
+
def start_chromedriver_container: (build_dir: untyped, mounts: untyped, shared_network: untyped) -> untyped
|
|
45
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Bidi2pdf
|
|
2
|
+
module TestHelpers
|
|
3
|
+
module Testcontainers
|
|
4
|
+
# Builds a URL for reaching a container's published port from the test
|
|
5
|
+
# process, using the container's own host/port resolution.
|
|
6
|
+
class ContainerEndpoint
|
|
7
|
+
@container: untyped
|
|
8
|
+
|
|
9
|
+
@port: untyped
|
|
10
|
+
|
|
11
|
+
def initialize: (untyped container, untyped port) -> void
|
|
12
|
+
|
|
13
|
+
def url: (?scheme: ::String, ?path: ::String) -> ::String
|
|
14
|
+
|
|
15
|
+
# Address reachable from another container on the same Docker network (e.g. remote-chrome
|
|
16
|
+
# reaching nginx), by alias and internal port - as opposed to #url's host-accessible,
|
|
17
|
+
# externally-mapped port. Uses the same @port this instance was built with, not a
|
|
18
|
+
# container_ports.first guess: the two methods must agree on which port they're both
|
|
19
|
+
# describing for the same container, or a caller comparing #url and #alias_url for what's
|
|
20
|
+
# meant to be the same endpoint could silently get two different services.
|
|
21
|
+
def alias_url: (?scheme: ::String, ?path: ::String) -> ::String
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|