chemlab 0.7.2 → 0.9.0

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: d84958e53d93ed46c4a4f93d1c236ae724b7f328ed010b0432ceef6c1ba23d21
4
- data.tar.gz: 78df858369ff4a789f328bfb75f6ef550a594456b2ab57b0dcf44dd294c2772e
3
+ metadata.gz: c09a8e6e3c407893b4df27fadd71ffff047f3ea3df27b34a1ad7f1c0b8119de9
4
+ data.tar.gz: c79979483ff6d8dc48716c3d6be27e683117bba9c346b925e6b7013e0d616238
5
5
  SHA512:
6
- metadata.gz: 2da525ce9135405cf917410515943d1542db46c4270f25ec5bbaa910b93f1d7a4fac83c8defa51ec9513e826c681bb22db2bd8721fe4561584d5588ae6019a02
7
- data.tar.gz: 99086cec60d34d42b25ea7415fdf464259e4742085d77e438fe9553692a176e4d5ad819f466c25e3c07841adeb4d17f1cff2a1f78d23f72632ab5dc1c395207f
6
+ metadata.gz: 96fc1f354f2b5568362c01688d265be896ca238f24819f075f1d16aa6b4f43c7b9cacf72662cd110d46dda4ee2bf6448b6a870927f9f1c9d2847fafa53949130
7
+ data.tar.gz: f1aa2b1677db2f65e134db511b4741fc4a8977c1d0098c1f5eb1f246a6107ab45576df778b93117b93b617e94234a481a4ebd58d5c4fa7417b505e4002cbbecd
@@ -17,6 +17,8 @@ module Chemlab
17
17
  default_value = nil
18
18
  default_value = yield if block_given?
19
19
 
20
+ attr_writer name
21
+
20
22
  define_method(name) do
21
23
  instance_variable_get("@#{name}") ||
22
24
  instance_variable_set(
@@ -46,18 +46,18 @@ module Chemlab
46
46
  public_elements << { type: watir_method, name: name, args: args }
47
47
 
48
48
  # @return [Watir::Element] the raw Watir element
49
- define_method("#{name}_element") do
50
- find_element(watir_method, name, args.first, &block)
49
+ define_method("#{name}_element") do |**find_args|
50
+ find_element(watir_method, name, args.first, **find_args, &block)
51
51
  end
52
52
 
53
53
  # @return [Boolean] true if the element is present
54
- define_method("#{name}?") do
55
- public_send("#{name}_element").present?
54
+ define_method("#{name}?") do |wait: nil, wait_until: nil|
55
+ public_send("#{name}_element", wait: wait, wait_until: wait_until).present?
56
56
  end
57
57
 
58
58
  # === GETTER / CLICKER === #
59
- define_method(name) do
60
- element = public_send("#{name}_element")
59
+ define_method(name) do |wait: nil, wait_until: :exists?|
60
+ element = public_send("#{name}_element", wait: wait, wait_until: wait_until)
61
61
  if Element::CLICKABLES.include? watir_method
62
62
  element.wait_until(&:present?).click
63
63
  elsif Element::INPUTS.include? watir_method
@@ -132,12 +132,59 @@ module Chemlab
132
132
  # @api private
133
133
  # @example
134
134
  # #find_element(:text_field, :username) #=>
135
- def find_element(watir_method, name, locator = nil, &block)
135
+ def find_element(watir_method, name, locator = nil, **args, &block)
136
136
  locator = { css: %([data-qa-selector="#{name}"]) } if locator.nil?
137
137
 
138
+ # extract extraneous arguments from the locator and insert them into args
139
+ chemlab_options, locator = extract_chemlab_options(locator)
140
+ args.merge!(chemlab_options)
141
+
142
+ old_timeout = Chemlab.configuration.default_timeout
143
+ args[:wait] ||= old_timeout
144
+
138
145
  return instance_exec(&block) if block_given?
139
146
 
140
- Chemlab.configuration.browser.session.engine.public_send(watir_method, locator).wait_until(&:exist?)
147
+ element = Chemlab.configuration.browser.session.engine.public_send(watir_method, locator)
148
+
149
+ return element if args[:wait_until].nil?
150
+
151
+ begin
152
+ # change timeout temporarily to the wait specified
153
+ change_timeout(args[:wait])
154
+
155
+ # perform wait(s) on the element
156
+ element.wait_until do |conditions|
157
+ break conditions.public_send(args[:wait_until]) unless args[:wait_until].respond_to?(:each)
158
+
159
+ args[:wait_until].each { |condition| conditions.public_send(condition) }
160
+ end
161
+
162
+ element
163
+ ensure
164
+ # reset timeout
165
+ change_timeout(old_timeout)
166
+ end
167
+ end
168
+
169
+ # Extract Chemlab specific options from an array
170
+ # @param [Array<Hash>] args given arguments
171
+ # @return [Array<Array<Hash>>] first array returned are the chemlab options, second is the resulting array
172
+ # @example
173
+ # arr = { id: 'test', foo: 'bar', wait: 10 }
174
+ # a, b = extract_chemlab_options!(**arr)
175
+ # a #=> { wait: 10 }
176
+ # b #=> { id: 'test', foo: 'bar' }
177
+ def extract_chemlab_options(**args)
178
+ [args.keys.each_with_object({}) do |arg, chemlab_opts|
179
+ chemlab_opts[arg] = args.delete(arg) if %i[wait wait_until].include?(arg)
180
+ end, args]
181
+ end
182
+
183
+ # Set / Reset default Chemlab timeout
184
+ # @param [Integer] timeout the timeout to set (defaults to +Chemlab.configuration.default_timeout)
185
+ # @return [Integer] the new timeout
186
+ def change_timeout(timeout = Chemlab.configuration.default_timeout)
187
+ Chemlab.configuration.default_timeout = timeout
141
188
  end
142
189
 
143
190
  protected
@@ -4,6 +4,8 @@ module Chemlab
4
4
  # Chemlab Configuration
5
5
  class Configuration
6
6
  include Runtime::Logger
7
+ include Attributable
8
+ extend Forwardable
7
9
 
8
10
  # Chemlab Terminal Banner
9
11
  BANNER = <<~'BANNER'
@@ -59,13 +61,13 @@ module Chemlab
59
61
  CONF
60
62
  end
61
63
 
62
- # Add a chemlab configuration
63
- def self.add_config(name)
64
- attr_accessor name
65
- end
64
+ attribute :base_url
65
+ attribute :hide_banner
66
66
 
67
- add_config :base_url
68
- add_config :hide_banner
67
+ # Delegate `default_timeout` to Watir.default_timeout
68
+ # Chemlab.configuration.default_timeout #=> Watir.default_timeout
69
+ # Chemlab.configuration.default_timeout = Watir.default_timeout = 30
70
+ def_delegators Watir, :default_timeout, :default_timeout=
69
71
 
70
72
  attr_reader :browser, :libraries
71
73
 
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Start monkey patch of String
4
+ class String
5
+ # Find the root module (parent module) of a class or module
6
+ # @example
7
+ # 'A::B::C'.root_module #=> A
8
+ # 'A::B'.root_module => A
9
+ # @return [Module] the root module
10
+ def root_module
11
+ Object.const_get(split('::').first)
12
+ end
13
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Chemlab
4
+ # Application Library Definition
5
+ # Provides accessors for +:base_url+, +:base_url=+
6
+ # +base_url+ will default to Chemlab's configured base_url
7
+ module Library
8
+ def self.included(base)
9
+ base.module_eval do
10
+ class << self
11
+ # The Base URL where this library / application exists
12
+ # If you have multiple applications that Chemlab will target,
13
+ # this is useful for having separate base_urls.
14
+ #
15
+ # @return [String] the base_url. +Chemlab.configuration.base_url+ by default if not set
16
+ #
17
+ # @example
18
+ # Chemlab.configure do |chemlab|
19
+ # A.base_url = 'https://first_app'
20
+ # B.base_url = 'https://second_app'
21
+ # chemlab.base_url = 'https://main_app'
22
+ #
23
+ # chemlab.libraries = [A, B, C]
24
+ #
25
+ # C.base_url #=> https://main_app
26
+ # end
27
+ attr_writer :base_url
28
+
29
+ def base_url
30
+ @base_url ||= Chemlab.configuration.base_url
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'forwardable'
4
+ require 'chemlab/core_ext/string/root_module'
4
5
 
5
6
  module Chemlab
6
7
  module Runtime
@@ -17,13 +18,56 @@ module Chemlab
17
18
  @session = Session.new(browser_options)
18
19
  end
19
20
 
21
+ # Navigate to a given Page library
22
+ # @param [Class<Chemlab::Page>] page_class the class of the Page to navigate to
23
+ # @example
24
+ # Given:
25
+ # module TheLibrary
26
+ # def self.base_url
27
+ # 'https://example.com'
28
+ # end
29
+ # class ThePage < Chemlab::Page
30
+ # path '/path'
31
+ # end
32
+ # end
33
+ #
34
+ # Chemlab::Runtime::Browser.navigate_to(TheLibrary::ThePage) #=> Navigates to https://example.com/path
35
+ #
36
+ # @example
37
+ # Given:
38
+ # Chemlab.configure do |chemlab|
39
+ # chemlab.base_url = 'https://example.com'
40
+ # end
41
+ #
42
+ # class ThePage < Chemlab::Page
43
+ # path '/'
44
+ # end
45
+ #
46
+ # Chemlab::Runtime::Browser.navigate_to(ThePage) #=> Navigates to https://example.com/path
20
47
  def self.navigate_to(page_class)
21
- Chemlab.configuration.browser.navigate_to(page_class.path)
48
+ unless page_class&.name.respond_to?(:root_module) && page_class.name.root_module.respond_to?(:base_url)
49
+ return Chemlab.configuration.browser.navigate_to(Chemlab.configuration.base_url + page_class.path)
50
+ end
51
+
52
+ # workaround for file:// protocol. URI.join() does not work with URI.join('file:///Users', '/user')
53
+ uri = if URI(page_class.name.root_module.base_url).scheme == 'file'
54
+ URI(File.join(page_class.name.root_module.base_url, page_class.path))
55
+ else
56
+ URI.join(page_class.name.root_module.base_url, page_class.path)
57
+ end
58
+
59
+ Chemlab.configuration.browser.navigate_to(uri)
22
60
  end
23
61
 
24
- def navigate_to(path)
62
+ # Navigate to a URI or Path
63
+ # @param [URI,String] uri_or_path the URI or path
64
+ # @return [URI,String] the URI or Path that was navigated to
65
+ # @example
66
+ # Chemlab.configuration.browser.navigate_to('/path') #=> /path
67
+ # Chemlab.configuration.browser.navigate_to(URI('https://example.com/path')) #=> URI('https://example.com/path')
68
+ def navigate_to(uri_or_path)
25
69
  @session ||= Chemlab.configuration.browser.session
26
- @session.engine.goto(Chemlab.configuration.base_url + path)
70
+ @session.engine.goto(uri_or_path.to_s)
27
71
  end
28
72
 
29
73
  # The options used to create the browser session
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Chemlab
4
- VERSION = '0.7.2'
4
+ VERSION = '0.9.0'
5
5
  end
data/lib/chemlab.rb CHANGED
@@ -34,6 +34,7 @@ module Chemlab
34
34
  autoload :Element, 'chemlab/element'
35
35
  autoload :Component, 'chemlab/component'
36
36
  autoload :Page, 'chemlab/page'
37
+ autoload :Library, 'chemlab/library'
37
38
 
38
39
  # Runtime modules
39
40
  module Runtime
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chemlab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab Quality
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-12 00:00:00.000000000 Z
11
+ date: 2021-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -240,7 +240,9 @@ files:
240
240
  - lib/chemlab/component.rb
241
241
  - lib/chemlab/configuration.rb
242
242
  - lib/chemlab/core_ext/string/inflections.rb
243
+ - lib/chemlab/core_ext/string/root_module.rb
243
244
  - lib/chemlab/element.rb
245
+ - lib/chemlab/library.rb
244
246
  - lib/chemlab/page.rb
245
247
  - lib/chemlab/runtime/browser.rb
246
248
  - lib/chemlab/runtime/env.rb
@@ -263,7 +265,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
263
265
  requirements:
264
266
  - - ">="
265
267
  - !ruby/object:Gem::Version
266
- version: 2.7.2
268
+ version: '2.5'
267
269
  required_rubygems_version: !ruby/object:Gem::Requirement
268
270
  requirements:
269
271
  - - ">="