datadog-ci 1.0.0.beta4 → 1.0.0.beta6
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/CHANGELOG.md +23 -2
- data/lib/datadog/ci/contrib/contrib.rb +31 -0
- data/lib/datadog/ci/contrib/minitest/reporter.rb +1 -1
- data/lib/datadog/ci/contrib/minitest/runnable.rb +1 -1
- data/lib/datadog/ci/contrib/minitest/runner.rb +1 -1
- data/lib/datadog/ci/contrib/rspec/example.rb +2 -1
- data/lib/datadog/ci/contrib/rspec/example_group.rb +1 -0
- data/lib/datadog/ci/contrib/rspec/knapsack_pro/extension.rb +0 -1
- data/lib/datadog/ci/contrib/rspec/knapsack_pro/patcher.rb +26 -0
- data/lib/datadog/ci/contrib/rspec/knapsack_pro/runner.rb +2 -1
- data/lib/datadog/ci/contrib/rspec/patcher.rb +6 -4
- data/lib/datadog/ci/contrib/rspec/runner.rb +2 -1
- data/lib/datadog/ci/contrib/selenium/capybara_driver.rb +45 -0
- data/lib/datadog/ci/contrib/selenium/configuration/settings.rb +32 -0
- data/lib/datadog/ci/contrib/selenium/driver.rb +45 -0
- data/lib/datadog/ci/contrib/selenium/ext.rb +30 -0
- data/lib/datadog/ci/contrib/selenium/integration.rb +48 -0
- data/lib/datadog/ci/contrib/selenium/navigation.rb +74 -0
- data/lib/datadog/ci/contrib/selenium/patcher.rb +36 -0
- data/lib/datadog/ci/contrib/selenium/rum.rb +45 -0
- data/lib/datadog/ci/ext/test.rb +18 -5
- data/lib/datadog/ci/ext/transport.rb +3 -0
- data/lib/datadog/ci/span.rb +5 -0
- data/lib/datadog/ci/test_visibility/recorder.rb +4 -0
- data/lib/datadog/ci/transport/api/agentless.rb +11 -3
- data/lib/datadog/ci/transport/gzip.rb +12 -0
- data/lib/datadog/ci/transport/http.rb +35 -3
- data/lib/datadog/ci/version.rb +1 -1
- data/lib/datadog/ci.rb +1 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a905eacfa2face6f297e027aa344b9b36f99d7f7f2120ab6946b2e9c650c390b
|
4
|
+
data.tar.gz: 537bd49690464320a74f88d9a0c392dcac10b83575407d703cf756a71ea8c29e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c87d7be67c31a970d0f6e75fcc4a0305719604afe02eac4061fd9c43a2539632f7a6f9199aafdaf55438913e721280ec2e5ac30f75d5921dd4bb3bdc1638f5a
|
7
|
+
data.tar.gz: '0838f7ce0df3bdf19a9a9c2c0df6c1b8ef0a96421e7043bfa339b6aa8d7a04f204a8c2a0dcb1cccb80f13df4a47a5da16c127a756d5064512120ea35a9beb8d0'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.0.0.beta6] - 2024-05-29
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
* Browser tests support via selenium integration ([#183][])
|
8
|
+
|
9
|
+
## [1.0.0.beta5] - 2024-05-23
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
* accept gzipped responses from API ([#170][])
|
14
|
+
|
15
|
+
### Fixed
|
16
|
+
|
17
|
+
* Fix Knapsack Pro integration ([#180][])
|
18
|
+
|
3
19
|
## [1.0.0.beta4] - 2024-05-14
|
4
20
|
|
5
21
|
### Added
|
@@ -238,7 +254,9 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
238
254
|
|
239
255
|
- Ruby versions < 2.7 no longer supported ([#8][])
|
240
256
|
|
241
|
-
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.
|
257
|
+
[Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta6...main
|
258
|
+
[1.0.0.beta6]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta5...v1.0.0.beta6
|
259
|
+
[1.0.0.beta5]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta4...v1.0.0.beta5
|
242
260
|
[1.0.0.beta4]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta3...v1.0.0.beta4
|
243
261
|
[1.0.0.beta3]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta2...v1.0.0.beta3
|
244
262
|
[1.0.0.beta2]: https://github.com/DataDog/datadog-ci-rb/compare/v1.0.0.beta1...v1.0.0.beta2
|
@@ -334,7 +352,10 @@ Currently test suite level visibility is not used by our instrumentation: it wil
|
|
334
352
|
[#166]: https://github.com/DataDog/datadog-ci-rb/issues/166
|
335
353
|
[#167]: https://github.com/DataDog/datadog-ci-rb/issues/167
|
336
354
|
[#168]: https://github.com/DataDog/datadog-ci-rb/issues/168
|
355
|
+
[#170]: https://github.com/DataDog/datadog-ci-rb/issues/170
|
337
356
|
[#172]: https://github.com/DataDog/datadog-ci-rb/issues/172
|
338
357
|
[#173]: https://github.com/DataDog/datadog-ci-rb/issues/173
|
339
358
|
[#174]: https://github.com/DataDog/datadog-ci-rb/issues/174
|
340
|
-
[#175]: https://github.com/DataDog/datadog-ci-rb/issues/175
|
359
|
+
[#175]: https://github.com/DataDog/datadog-ci-rb/issues/175
|
360
|
+
[#180]: https://github.com/DataDog/datadog-ci-rb/issues/180
|
361
|
+
[#183]: https://github.com/DataDog/datadog-ci-rb/issues/183
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "integration"
|
4
|
+
|
5
|
+
module Datadog
|
6
|
+
module CI
|
7
|
+
module Contrib
|
8
|
+
# This method auto instruments all test libraries (ex: selenium-webdriver).
|
9
|
+
# It is intended to be called when test session starts to add additional capabilities to test visibility.
|
10
|
+
#
|
11
|
+
# This method does not automatically instrument test frameworks (ex: RSpec, Cucumber, etc), it requires
|
12
|
+
# test framework to be already instrumented.
|
13
|
+
def self.auto_instrument_on_session_start!
|
14
|
+
Datadog.logger.debug("Auto instrumenting all integrations...")
|
15
|
+
|
16
|
+
Integration.registry.each do |name, integration|
|
17
|
+
next unless integration.auto_instrument?
|
18
|
+
|
19
|
+
Datadog.logger.debug "#{name} is allowed to be auto instrumented"
|
20
|
+
|
21
|
+
patch_results = integration.patch
|
22
|
+
if patch_results == true
|
23
|
+
Datadog.logger.debug("#{name} is patched")
|
24
|
+
else
|
25
|
+
Datadog.logger.debug("#{name} is not patched (#{patch_results})")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -16,6 +16,7 @@ module Datadog
|
|
16
16
|
# Instance methods for configuration
|
17
17
|
module ClassMethods
|
18
18
|
def run(reporter = ::RSpec::Core::NullReporter)
|
19
|
+
return super if ::RSpec.configuration.dry_run?
|
19
20
|
return super unless datadog_configuration[:enabled]
|
20
21
|
return super unless top_level?
|
21
22
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Contrib
|
6
|
+
module RSpec
|
7
|
+
module KnapsackPro
|
8
|
+
module Patcher
|
9
|
+
def self.patch
|
10
|
+
if defined?(::KnapsackPro::Extensions::RSpecExtension::Runner) &&
|
11
|
+
::RSpec::Core::Runner.ancestors.include?(::KnapsackPro::Extensions::RSpecExtension::Runner)
|
12
|
+
# knapsack already patched rspec runner
|
13
|
+
require_relative "runner"
|
14
|
+
::RSpec::Core::Runner.include(KnapsackPro::Runner)
|
15
|
+
else
|
16
|
+
# knapsack didn't patch rspec runner yet
|
17
|
+
require_relative "extension"
|
18
|
+
::KnapsackPro::Extensions::RSpecExtension.include(KnapsackPro::Extension)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -14,7 +14,8 @@ module Datadog
|
|
14
14
|
end
|
15
15
|
|
16
16
|
module InstanceMethods
|
17
|
-
def knapsack__run_specs(*)
|
17
|
+
def knapsack__run_specs(*args)
|
18
|
+
return super if ::RSpec.configuration.dry_run?
|
18
19
|
return super unless datadog_configuration[:enabled]
|
19
20
|
|
20
21
|
test_session = CI.start_test_session(
|
@@ -27,14 +27,16 @@ module Datadog
|
|
27
27
|
::RSpec::Queue::Runner.include(Runner)
|
28
28
|
end
|
29
29
|
|
30
|
-
# Knapsack Pro test runner instrumentation
|
31
|
-
# https://github.com/KnapsackPro/knapsack_pro-ruby
|
32
30
|
if knapsack_pro?
|
33
|
-
|
34
|
-
|
31
|
+
# Knapsack Pro test runner instrumentation
|
32
|
+
# https://github.com/KnapsackPro/knapsack_pro-ruby
|
33
|
+
require_relative "knapsack_pro/patcher"
|
34
|
+
Datadog::CI::Contrib::RSpec::KnapsackPro::Patcher.patch
|
35
35
|
end
|
36
36
|
|
37
|
+
# default rspec test runner instrumentation
|
37
38
|
::RSpec::Core::Runner.include(Runner)
|
39
|
+
|
38
40
|
::RSpec::Core::Example.include(Example)
|
39
41
|
::RSpec::Core::ExampleGroup.include(ExampleGroup)
|
40
42
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/tracing/contrib/patcher"
|
4
|
+
|
5
|
+
require_relative "ext"
|
6
|
+
require_relative "rum"
|
7
|
+
require_relative "../../ext/test"
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module CI
|
11
|
+
module Contrib
|
12
|
+
module Selenium
|
13
|
+
# instruments Capybara::Selenium::Driver
|
14
|
+
module CapybaraDriver
|
15
|
+
def self.included(base)
|
16
|
+
base.prepend(InstanceMethods)
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def reset!
|
21
|
+
return super unless datadog_configuration[:enabled]
|
22
|
+
|
23
|
+
Datadog.logger.debug("[Selenium] Capybara session reset event")
|
24
|
+
|
25
|
+
RUM.stop_rum_session(@browser)
|
26
|
+
|
27
|
+
Datadog.logger.debug("[Selenium] RUM session stopped, deleting cookie")
|
28
|
+
@browser.manage.delete_cookie(Ext::COOKIE_TEST_EXECUTION_ID)
|
29
|
+
rescue ::Selenium::WebDriver::Error::WebDriverError => e
|
30
|
+
Datadog.logger.debug("[Selenium] Error while resetting Capybara session: #{e.message}")
|
31
|
+
ensure
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def datadog_configuration
|
38
|
+
Datadog.configuration.ci[:selenium]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/core"
|
4
|
+
|
5
|
+
require_relative "../ext"
|
6
|
+
require_relative "../../settings"
|
7
|
+
|
8
|
+
module Datadog
|
9
|
+
module CI
|
10
|
+
module Contrib
|
11
|
+
module Selenium
|
12
|
+
module Configuration
|
13
|
+
# Custom settings for the Selenium integration
|
14
|
+
# @public_api
|
15
|
+
class Settings < Datadog::CI::Contrib::Settings
|
16
|
+
option :enabled do |o|
|
17
|
+
o.type :bool
|
18
|
+
o.env Ext::ENV_ENABLED
|
19
|
+
o.default true
|
20
|
+
end
|
21
|
+
|
22
|
+
option :rum_flush_wait_millis do |o|
|
23
|
+
o.type :int
|
24
|
+
o.env Ext::ENV_RUM_FLUSH_WAIT_MILLIS
|
25
|
+
o.default 500
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/tracing/contrib/patcher"
|
4
|
+
|
5
|
+
require_relative "ext"
|
6
|
+
require_relative "rum"
|
7
|
+
require_relative "../../ext/test"
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module CI
|
11
|
+
module Contrib
|
12
|
+
module Selenium
|
13
|
+
# instruments Selenium::WebDriver::Driver
|
14
|
+
module Driver
|
15
|
+
def self.included(base)
|
16
|
+
base.prepend(InstanceMethods)
|
17
|
+
end
|
18
|
+
|
19
|
+
module InstanceMethods
|
20
|
+
def quit
|
21
|
+
return super unless datadog_configuration[:enabled]
|
22
|
+
|
23
|
+
Datadog.logger.debug("[Selenium] Driver quit event")
|
24
|
+
|
25
|
+
RUM.stop_rum_session(@bridge)
|
26
|
+
|
27
|
+
Datadog.logger.debug("[Selenium] RUM session stopped, deleting cookie")
|
28
|
+
@bridge.manage.delete_cookie(Ext::COOKIE_TEST_EXECUTION_ID)
|
29
|
+
rescue ::Selenium::WebDriver::Error::WebDriverError => e
|
30
|
+
Datadog.logger.debug("[Selenium] Error while quitting Selenium driver: #{e.message}")
|
31
|
+
ensure
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def datadog_configuration
|
38
|
+
Datadog.configuration.ci[:selenium]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module CI
|
5
|
+
module Contrib
|
6
|
+
module Selenium
|
7
|
+
# Selenium integration constants
|
8
|
+
# @public_api
|
9
|
+
module Ext
|
10
|
+
ENV_ENABLED = "DD_CIVISIBILITY_SELENIUM_ENABLED"
|
11
|
+
ENV_RUM_FLUSH_WAIT_MILLIS = "DD_CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS"
|
12
|
+
|
13
|
+
COOKIE_TEST_EXECUTION_ID = "datadog-ci-visibility-test-execution-id"
|
14
|
+
|
15
|
+
SCRIPT_IS_RUM_ACTIVE = <<~JS
|
16
|
+
return !!window.DD_RUM
|
17
|
+
JS
|
18
|
+
SCRIPT_STOP_RUM_SESSION = <<~JS
|
19
|
+
if (window.DD_RUM && window.DD_RUM.stopSession) {
|
20
|
+
window.DD_RUM.stopSession();
|
21
|
+
return true;
|
22
|
+
} else {
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
JS
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../integration"
|
4
|
+
require_relative "configuration/settings"
|
5
|
+
require_relative "patcher"
|
6
|
+
|
7
|
+
module Datadog
|
8
|
+
module CI
|
9
|
+
module Contrib
|
10
|
+
module Selenium
|
11
|
+
# Description of Selenium integration
|
12
|
+
class Integration
|
13
|
+
include Datadog::CI::Contrib::Integration
|
14
|
+
|
15
|
+
MINIMUM_VERSION = Gem::Version.new("4.0.0")
|
16
|
+
|
17
|
+
register_as :selenium
|
18
|
+
|
19
|
+
def self.version
|
20
|
+
Gem.loaded_specs["selenium-webdriver"]&.version
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.loaded?
|
24
|
+
!defined?(::Selenium).nil? && !defined?(::Selenium::WebDriver).nil? &&
|
25
|
+
!defined?(::Selenium::WebDriver::Driver).nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.compatible?
|
29
|
+
super && version >= MINIMUM_VERSION
|
30
|
+
end
|
31
|
+
|
32
|
+
# additional instrumentations for test helpers are auto instrumented on test session start
|
33
|
+
def auto_instrument?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def new_configuration
|
38
|
+
Configuration::Settings.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def patcher
|
42
|
+
Patcher
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/tracing/contrib/patcher"
|
4
|
+
|
5
|
+
require_relative "ext"
|
6
|
+
require_relative "../../ext/test"
|
7
|
+
|
8
|
+
module Datadog
|
9
|
+
module CI
|
10
|
+
module Contrib
|
11
|
+
module Selenium
|
12
|
+
# instruments Selenium::WebDriver::Navigation
|
13
|
+
module Navigation
|
14
|
+
def self.included(base)
|
15
|
+
base.prepend(InstanceMethods)
|
16
|
+
end
|
17
|
+
|
18
|
+
module InstanceMethods
|
19
|
+
def to(url)
|
20
|
+
result = super
|
21
|
+
|
22
|
+
return result unless datadog_configuration[:enabled]
|
23
|
+
|
24
|
+
Datadog.logger.debug("[Selenium] Navigation to #{url}")
|
25
|
+
|
26
|
+
# on session reset Capybara navigates to about:blank
|
27
|
+
return result if url == "about:blank"
|
28
|
+
|
29
|
+
active_test = Datadog::CI.active_test
|
30
|
+
Datadog.logger.debug("[Selenium] Active test: #{active_test}")
|
31
|
+
|
32
|
+
return result unless active_test
|
33
|
+
|
34
|
+
# Set the test's trace id as a cookie in browser session
|
35
|
+
cookie_hash = {name: Ext::COOKIE_TEST_EXECUTION_ID, value: active_test.trace_id.to_s}
|
36
|
+
Datadog.logger.debug { "[Selenium] Setting cookie: #{cookie_hash}" }
|
37
|
+
@bridge.manage.add_cookie(cookie_hash)
|
38
|
+
|
39
|
+
# set the test type to browser
|
40
|
+
active_test.set_tag(CI::Ext::Test::TAG_TYPE, CI::Ext::Test::Type::BROWSER)
|
41
|
+
|
42
|
+
# set the tags specific to the browser test
|
43
|
+
active_test.set_tag(CI::Ext::Test::TAG_BROWSER_DRIVER, "selenium")
|
44
|
+
active_test.set_tag(
|
45
|
+
CI::Ext::Test::TAG_BROWSER_DRIVER_VERSION,
|
46
|
+
Integration.version
|
47
|
+
)
|
48
|
+
active_test.set_tag(
|
49
|
+
CI::Ext::Test::TAG_BROWSER_NAME,
|
50
|
+
@bridge.browser
|
51
|
+
)
|
52
|
+
active_test.set_tag(
|
53
|
+
CI::Ext::Test::TAG_BROWSER_VERSION,
|
54
|
+
@bridge.capabilities.browser_version
|
55
|
+
)
|
56
|
+
|
57
|
+
result
|
58
|
+
rescue ::Selenium::WebDriver::Error::WebDriverError => e
|
59
|
+
Datadog.logger.debug("[Selenium] Error while navigating: #{e.message}")
|
60
|
+
|
61
|
+
result
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def datadog_configuration
|
67
|
+
Datadog.configuration.ci[:selenium]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/tracing/contrib/patcher"
|
4
|
+
|
5
|
+
require_relative "capybara_driver"
|
6
|
+
require_relative "driver"
|
7
|
+
require_relative "navigation"
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module CI
|
11
|
+
module Contrib
|
12
|
+
module Selenium
|
13
|
+
# Patcher enables patching of 'Selenium::WebDriver' module.
|
14
|
+
module Patcher
|
15
|
+
include Datadog::Tracing::Contrib::Patcher
|
16
|
+
|
17
|
+
module_function
|
18
|
+
|
19
|
+
def target_version
|
20
|
+
Integration.version
|
21
|
+
end
|
22
|
+
|
23
|
+
def patch
|
24
|
+
::Selenium::WebDriver::Driver.include(Driver)
|
25
|
+
::Selenium::WebDriver::Navigation.include(Navigation)
|
26
|
+
|
27
|
+
# capybara calls `reset!` after each test, so we need to patch it as well
|
28
|
+
if defined?(::Capybara::Selenium::Driver)
|
29
|
+
::Capybara::Selenium::Driver.include(CapybaraDriver)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "datadog/tracing/contrib/patcher"
|
4
|
+
|
5
|
+
require_relative "ext"
|
6
|
+
require_relative "../../ext/test"
|
7
|
+
require_relative "../../utils/parsing"
|
8
|
+
|
9
|
+
module Datadog
|
10
|
+
module CI
|
11
|
+
module Contrib
|
12
|
+
module Selenium
|
13
|
+
# Provides functionality to interact with Datadog Real User Monitoring product
|
14
|
+
# via executing JavaScript code in the browser.
|
15
|
+
#
|
16
|
+
# Relevant docs: https://docs.datadoghq.com/real_user_monitoring/browser/
|
17
|
+
module RUM
|
18
|
+
def self.is_rum_active?(script_executor)
|
19
|
+
is_rum_active_script_result = script_executor.execute_script(Ext::SCRIPT_IS_RUM_ACTIVE)
|
20
|
+
Datadog.logger.debug { "[Selenium] SCRIPT_IS_RUM_ACTIVE result is #{is_rum_active_script_result.inspect}" }
|
21
|
+
Utils::Parsing.convert_to_bool(is_rum_active_script_result)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.stop_rum_session(script_executor)
|
25
|
+
config = Datadog.configuration.ci[:selenium]
|
26
|
+
if is_rum_active?(script_executor)
|
27
|
+
Datadog::CI.active_test&.set_tag(
|
28
|
+
CI::Ext::Test::TAG_IS_RUM_ACTIVE,
|
29
|
+
"true"
|
30
|
+
)
|
31
|
+
|
32
|
+
result = script_executor.execute_script(Ext::SCRIPT_STOP_RUM_SESSION)
|
33
|
+
Datadog.logger.debug { "[Selenium] SCRIPT_STOP_RUM_SESSION result is #{result.inspect}" }
|
34
|
+
|
35
|
+
# introduce a delay to allow the RUM session to be stopped
|
36
|
+
delay = config[:rum_flush_wait_millis] / 1000.0
|
37
|
+
Datadog.logger.debug { "[Selenium] Waiting for #{delay} seconds" }
|
38
|
+
sleep(delay)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/datadog/ci/ext/test.rb
CHANGED
@@ -8,6 +8,7 @@ module Datadog
|
|
8
8
|
module Test
|
9
9
|
CONTEXT_ORIGIN = "ciapp-test"
|
10
10
|
|
11
|
+
# Base test visibility tags
|
11
12
|
TAG_FRAMEWORK = "test.framework"
|
12
13
|
TAG_FRAMEWORK_VERSION = "test.framework_version"
|
13
14
|
TAG_NAME = "test.name"
|
@@ -34,16 +35,13 @@ module Datadog
|
|
34
35
|
# Code coverage tags
|
35
36
|
TAG_CODE_COVERAGE_ENABLED = "test.code_coverage.enabled"
|
36
37
|
|
37
|
-
#
|
38
|
-
#
|
38
|
+
# Special tags, not sent to the backend.
|
39
|
+
# these tags are special and used to correlate tests with the test sessions, suites, and modules
|
39
40
|
TAG_TEST_SESSION_ID = "_test.session_id"
|
40
41
|
TAG_TEST_MODULE_ID = "_test.module_id"
|
41
42
|
TAG_TEST_SUITE_ID = "_test.suite_id"
|
42
43
|
TRANSIENT_TAGS = [TAG_TEST_SESSION_ID, TAG_TEST_MODULE_ID, TAG_TEST_SUITE_ID].freeze
|
43
44
|
|
44
|
-
# tags that are common for the whole session and can be inherited from the test session
|
45
|
-
INHERITABLE_TAGS = [TAG_FRAMEWORK, TAG_FRAMEWORK_VERSION].freeze
|
46
|
-
|
47
45
|
# Environment runtime tags
|
48
46
|
TAG_OS_ARCHITECTURE = "os.architecture"
|
49
47
|
TAG_OS_PLATFORM = "os.platform"
|
@@ -51,10 +49,24 @@ module Datadog
|
|
51
49
|
TAG_RUNTIME_NAME = "runtime.name"
|
52
50
|
TAG_RUNTIME_VERSION = "runtime.version"
|
53
51
|
|
52
|
+
# Tags for browser tests
|
53
|
+
# true if Datadog RUM was detected in the page(s) loaded by Selenium
|
54
|
+
TAG_IS_RUM_ACTIVE = "test.is_rum_active"
|
55
|
+
TAG_BROWSER_DRIVER = "test.browser.driver"
|
56
|
+
# version of selenium driver used
|
57
|
+
TAG_BROWSER_DRIVER_VERSION = "test.browser.driver_version"
|
58
|
+
# name of the browser (Chrome, Firefox, Edge, etc), if multiple browsers then this tag is empty
|
59
|
+
TAG_BROWSER_NAME = "test.browser.name"
|
60
|
+
# version of the browser, if multiple browsers or multiple versions then this tag is empty
|
61
|
+
TAG_BROWSER_VERSION = "test.browser.version"
|
62
|
+
|
54
63
|
# internal APM tag to mark a span as a test span
|
55
64
|
TAG_SPAN_KIND = "span.kind"
|
56
65
|
SPAN_KIND_TEST = "test"
|
57
66
|
|
67
|
+
# tags that are common for the whole session and can be inherited from the test session
|
68
|
+
INHERITABLE_TAGS = [TAG_FRAMEWORK, TAG_FRAMEWORK_VERSION].freeze
|
69
|
+
|
58
70
|
# could be either "test" or "suite" depending on whether we skip individual tests or whole suites
|
59
71
|
# we use test skipping for Ruby
|
60
72
|
ITR_TEST_SKIPPING_MODE = "test"
|
@@ -71,6 +83,7 @@ module Datadog
|
|
71
83
|
# test types (e.g. test, benchmark, browser)
|
72
84
|
module Type
|
73
85
|
TEST = "test"
|
86
|
+
BROWSER = "browser"
|
74
87
|
BENCHMARK = "benchmark" # DEV: not used yet, will be used when benchmarks are supported
|
75
88
|
end
|
76
89
|
end
|
@@ -7,6 +7,7 @@ module Datadog
|
|
7
7
|
DEFAULT_DD_SITE = "datadoghq.com"
|
8
8
|
|
9
9
|
HEADER_DD_API_KEY = "DD-API-KEY"
|
10
|
+
HEADER_ACCEPT_ENCODING = "Accept-Encoding"
|
10
11
|
HEADER_CONTENT_TYPE = "Content-Type"
|
11
12
|
HEADER_CONTENT_ENCODING = "Content-Encoding"
|
12
13
|
HEADER_EVP_SUBDOMAIN = "X-Datadog-EVP-Subdomain"
|
@@ -48,6 +49,8 @@ module Datadog
|
|
48
49
|
CONTENT_TYPE_JSON = "application/json"
|
49
50
|
CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data"
|
50
51
|
CONTENT_ENCODING_GZIP = "gzip"
|
52
|
+
|
53
|
+
GZIP_MAGIC_NUMBER = "\x1F\x8B".b
|
51
54
|
end
|
52
55
|
end
|
53
56
|
end
|
data/lib/datadog/ci/span.rb
CHANGED
@@ -10,6 +10,7 @@ require_relative "context/global"
|
|
10
10
|
require_relative "context/local"
|
11
11
|
|
12
12
|
require_relative "../codeowners/parser"
|
13
|
+
require_relative "../contrib/contrib"
|
13
14
|
require_relative "../ext/app_types"
|
14
15
|
require_relative "../ext/test"
|
15
16
|
require_relative "../ext/environment"
|
@@ -57,6 +58,9 @@ module Datadog
|
|
57
58
|
def start_test_session(service: nil, tags: {})
|
58
59
|
return skip_tracing unless test_suite_level_visibility_enabled
|
59
60
|
|
61
|
+
# finds and instruments additional test libraries that we support (ex: selenium-webdriver)
|
62
|
+
Contrib.auto_instrument_on_session_start!
|
63
|
+
|
60
64
|
@global_context.fetch_or_activate_test_session do
|
61
65
|
tracer_span = start_datadog_tracer_span(
|
62
66
|
"test.session", build_span_options(service, Ext::AppTypes::TYPE_TEST_SESSION)
|
@@ -26,7 +26,14 @@ module Datadog
|
|
26
26
|
def api_request(path:, payload:, headers: {}, verb: "post")
|
27
27
|
super
|
28
28
|
|
29
|
-
perform_request(
|
29
|
+
perform_request(
|
30
|
+
@api_http,
|
31
|
+
path: path,
|
32
|
+
payload: payload,
|
33
|
+
headers: headers,
|
34
|
+
verb: verb,
|
35
|
+
accept_compressed_response: true
|
36
|
+
)
|
30
37
|
end
|
31
38
|
|
32
39
|
def citestcov_request(path:, payload:, headers: {}, verb: "post")
|
@@ -37,12 +44,13 @@ module Datadog
|
|
37
44
|
|
38
45
|
private
|
39
46
|
|
40
|
-
def perform_request(http_client, path:, payload:, headers:, verb:)
|
47
|
+
def perform_request(http_client, path:, payload:, headers:, verb:, accept_compressed_response: false)
|
41
48
|
http_client.request(
|
42
49
|
path: path,
|
43
50
|
payload: payload,
|
44
51
|
headers: headers_with_default(headers),
|
45
|
-
verb: verb
|
52
|
+
verb: verb,
|
53
|
+
accept_compressed_response: accept_compressed_response
|
46
54
|
)
|
47
55
|
end
|
48
56
|
|
@@ -16,6 +16,18 @@ module Datadog
|
|
16
16
|
gzip_writer.close
|
17
17
|
sio.string
|
18
18
|
end
|
19
|
+
|
20
|
+
def decompress(input)
|
21
|
+
sio = StringIO.new(input)
|
22
|
+
gzip_reader = Zlib::GzipReader.new(
|
23
|
+
sio,
|
24
|
+
external_encoding: Encoding::UTF_8,
|
25
|
+
internal_encoding: Encoding::UTF_8
|
26
|
+
)
|
27
|
+
gzip_reader.read || ""
|
28
|
+
ensure
|
29
|
+
gzip_reader&.close
|
30
|
+
end
|
19
31
|
end
|
20
32
|
end
|
21
33
|
end
|
@@ -32,12 +32,24 @@ module Datadog
|
|
32
32
|
@compress = compress.nil? ? false : compress
|
33
33
|
end
|
34
34
|
|
35
|
-
def request(
|
35
|
+
def request(
|
36
|
+
path:,
|
37
|
+
payload:,
|
38
|
+
headers:,
|
39
|
+
verb: "post",
|
40
|
+
retries: MAX_RETRIES,
|
41
|
+
backoff: INITIAL_BACKOFF,
|
42
|
+
accept_compressed_response: false
|
43
|
+
)
|
36
44
|
if compress
|
37
45
|
headers[Ext::Transport::HEADER_CONTENT_ENCODING] = Ext::Transport::CONTENT_ENCODING_GZIP
|
38
46
|
payload = Gzip.compress(payload)
|
39
47
|
end
|
40
48
|
|
49
|
+
if accept_compressed_response
|
50
|
+
headers[Ext::Transport::HEADER_ACCEPT_ENCODING] = Ext::Transport::CONTENT_ENCODING_GZIP
|
51
|
+
end
|
52
|
+
|
41
53
|
Datadog.logger.debug do
|
42
54
|
"Sending #{verb} request: host=#{host}; port=#{port}; ssl_enabled=#{ssl}; " \
|
43
55
|
"compression_enabled=#{compress}; path=#{path}; payload_size=#{payload.size}"
|
@@ -91,12 +103,32 @@ module Datadog
|
|
91
103
|
@adapter ||= Datadog::Core::Transport::HTTP::Adapters::Net.new(settings)
|
92
104
|
end
|
93
105
|
|
94
|
-
#
|
95
|
-
#
|
106
|
+
# adds compatibility with Datadog::Tracing transport and
|
107
|
+
# provides ungzipping capabilities
|
96
108
|
class ResponseDecorator < ::SimpleDelegator
|
109
|
+
def payload
|
110
|
+
return @decompressed_payload if defined?(@decompressed_payload)
|
111
|
+
|
112
|
+
if gzipped?(__getobj__.payload)
|
113
|
+
Datadog.logger.debug("Decompressing gzipped response payload")
|
114
|
+
@decompressed_payload = Gzip.decompress(__getobj__.payload)
|
115
|
+
else
|
116
|
+
__getobj__.payload
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
97
120
|
def trace_count
|
98
121
|
0
|
99
122
|
end
|
123
|
+
|
124
|
+
def gzipped?(payload)
|
125
|
+
return false if payload.nil? || payload.empty?
|
126
|
+
|
127
|
+
first_bytes = payload[0, 2]
|
128
|
+
return false if first_bytes.nil? || first_bytes.empty?
|
129
|
+
|
130
|
+
first_bytes.b == Datadog::CI::Ext::Transport::GZIP_MAGIC_NUMBER
|
131
|
+
end
|
100
132
|
end
|
101
133
|
|
102
134
|
class AdapterSettings
|
data/lib/datadog/ci/version.rb
CHANGED
data/lib/datadog/ci.rb
CHANGED
@@ -376,6 +376,7 @@ end
|
|
376
376
|
require_relative "ci/contrib/cucumber/integration"
|
377
377
|
require_relative "ci/contrib/rspec/integration"
|
378
378
|
require_relative "ci/contrib/minitest/integration"
|
379
|
+
require_relative "ci/contrib/selenium/integration"
|
379
380
|
|
380
381
|
# Configuration extensions
|
381
382
|
require_relative "ci/configuration/extensions"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datadog-ci
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Datadog, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: datadog
|
@@ -66,6 +66,7 @@ files:
|
|
66
66
|
- lib/datadog/ci/configuration/components.rb
|
67
67
|
- lib/datadog/ci/configuration/extensions.rb
|
68
68
|
- lib/datadog/ci/configuration/settings.rb
|
69
|
+
- lib/datadog/ci/contrib/contrib.rb
|
69
70
|
- lib/datadog/ci/contrib/cucumber/configuration/settings.rb
|
70
71
|
- lib/datadog/ci/contrib/cucumber/ext.rb
|
71
72
|
- lib/datadog/ci/contrib/cucumber/formatter.rb
|
@@ -89,9 +90,18 @@ files:
|
|
89
90
|
- lib/datadog/ci/contrib/rspec/ext.rb
|
90
91
|
- lib/datadog/ci/contrib/rspec/integration.rb
|
91
92
|
- lib/datadog/ci/contrib/rspec/knapsack_pro/extension.rb
|
93
|
+
- lib/datadog/ci/contrib/rspec/knapsack_pro/patcher.rb
|
92
94
|
- lib/datadog/ci/contrib/rspec/knapsack_pro/runner.rb
|
93
95
|
- lib/datadog/ci/contrib/rspec/patcher.rb
|
94
96
|
- lib/datadog/ci/contrib/rspec/runner.rb
|
97
|
+
- lib/datadog/ci/contrib/selenium/capybara_driver.rb
|
98
|
+
- lib/datadog/ci/contrib/selenium/configuration/settings.rb
|
99
|
+
- lib/datadog/ci/contrib/selenium/driver.rb
|
100
|
+
- lib/datadog/ci/contrib/selenium/ext.rb
|
101
|
+
- lib/datadog/ci/contrib/selenium/integration.rb
|
102
|
+
- lib/datadog/ci/contrib/selenium/navigation.rb
|
103
|
+
- lib/datadog/ci/contrib/selenium/patcher.rb
|
104
|
+
- lib/datadog/ci/contrib/selenium/rum.rb
|
95
105
|
- lib/datadog/ci/contrib/settings.rb
|
96
106
|
- lib/datadog/ci/ext/app_types.rb
|
97
107
|
- lib/datadog/ci/ext/environment.rb
|