leap_salesforce_ui 0.1.4 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3481b31ac19a98f7d9fe40b017f0d9d2d047a50a891ed20e079aaee480c0c623
4
- data.tar.gz: 72ec8083bcfe9155f7e631fd5354c9d8388104bf9007985440a2518e902576f8
3
+ metadata.gz: 4b5f251c39643a21857de6fe166d4bd7e7b745a124447c8902e1c37b668e9505
4
+ data.tar.gz: 0ede5e19a5b0ad7bde0c7225839b3491befddf121f841a814553b7f61b4ebff4
5
5
  SHA512:
6
- metadata.gz: 34b181f68921877a0e0afe55fd9e4ce91f3273323065c034f8dd63e0e0b85341e1ca27187b6f8e773e25816935615c6e33baf7aab262cf65244eebfdc217de2b
7
- data.tar.gz: 9d7d119547de5453559936160ecc520e6d0db99620050c38b6297998b3f99e3e5938bb6875621bc2cdbee698c2d6e1f817743291fa15fb6c08a1435be39d2cd6
6
+ metadata.gz: 74c998b5c42ec3d31f3c4e730c294b05cbcaae389a7be5dc9c8425f0a8f994618694b1e4fc0274649705fa0ab4d558e159c69a133907a4de5ae3521a7511fffb
7
+ data.tar.gz: 5604e708d5d9c28cf03d797cbff9373e33e4481e69b99ebbee961df091eb30f0c8a97ae504bea2025995b4edf43f979002e8fd75d1e513110a4d43a7cd077065
data/.leap_salesforce.yml CHANGED
@@ -4,3 +4,4 @@ sfdx: false
4
4
  soql_objects:
5
5
  - Contact
6
6
  - Account
7
+ - Broker: Broker__c
data/ChangeLog CHANGED
@@ -1,3 +1,21 @@
1
+ Version 0.1.8
2
+ * Fixed Watir version at 6.19. Need to update syntax to work with latest version
3
+
4
+ Version 0.1.7
5
+ * Fixed filling in form for Salesforce's new layout
6
+
7
+ Version 0.1.6
8
+ * Bug fix
9
+ * Not appending to Gemfile meant Rakefile could not load leap_salesfore_ui rake tasks
10
+
11
+ Version 0.1.5
12
+ * Enhancements
13
+ * Added logging of actions
14
+ * Allow headless mode with LeapSalesforce.headless = true
15
+ * Throw custom errors when problem occurs setting fields
16
+ * Bug fix
17
+ * Didn't handle where class name and backend name differ
18
+
1
19
  Version 0.1.4
2
20
  * Enhancements
3
21
  * Add executable to make it fast to setup testing with exe `leap_salesforce_ui init`
data/README.md CHANGED
@@ -125,6 +125,14 @@ Follow other examples in `spec` to build tests using the auto-generated classes.
125
125
  unless run from an IP address that your Salesforce Org trusts. Many shared CI environments have runners that would
126
126
  be hard to whitelist as the address is dynamic.
127
127
 
128
+ ### Options
129
+
130
+ To run tests in headless mode, set headless mode to true.
131
+ ```ruby
132
+ LeapSalesforce.headless = true
133
+ ```
134
+
135
+
128
136
  ## Development
129
137
 
130
138
  After checking out the repo, run `bin/setup` to install dependencies.
data/bin/console CHANGED
File without changes
data/bin/setup CHANGED
File without changes
@@ -31,6 +31,7 @@ module LeapSalesforce
31
31
  def init
32
32
  puts "Initialising initial files to get started with leap_salesforce_ui"
33
33
  append "Rakefile", "Rakefile.erb"
34
+ append "Gemfile", "Gemfile.erb"
34
35
  puts 'Running Rake task "leaps:create_poms"'
35
36
  puts `rake leaps:create_poms`
36
37
  append File.join("spec", "spec_helper.rb"), "spec_helper.rb.erb"
@@ -30,7 +30,7 @@ It reads the Metadata from Salesforce and creates the foundation for UI tests.'
30
30
  spec.require_paths = ["lib"]
31
31
 
32
32
  spec.add_dependency "leap_salesforce", ">= 1.0.3"
33
- spec.add_dependency "watir", ">= 6.17.0"
33
+ spec.add_dependency "watir", "6.19"
34
34
  spec.add_dependency "webdrivers"
35
35
 
36
36
  # For more information and examples about making a new gem, checkout our
@@ -8,13 +8,17 @@ module BasePage
8
8
  LeapSalesforce.browser
9
9
  end
10
10
 
11
+ # Set entity this page object refers to
12
+ # @param [Class] soql_object Backend name of SoqlObject this page object refers to
11
13
  def soql_object(soql_object)
12
14
  @soql_object = soql_object
13
15
  end
14
16
 
17
+ # Visit the current page, logging in if required
15
18
  def visit
16
19
  LoginPage.login
17
- page_url = "#{SoqlHandler.instance_url}/lightning/o/#{@soql_object}/new"
20
+ page_url = "#{SoqlHandler.instance_url}/lightning/o/#{@soql_object.soql_object_name}/new"
21
+ LeapSalesforce.logger.info "Visiting #{self}"
18
22
  browser.goto page_url
19
23
  self
20
24
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LeapSalesforce
4
+ # Error related to submitting a form
5
+ class SubmitError < Error; end
6
+
7
+ # Error related to setting a field
8
+ class SetFieldError < Error; end
9
+ end
@@ -2,7 +2,8 @@
2
2
 
3
3
  module LeapSalesforce
4
4
  module FormFiller
5
- def new_panel
5
+ # @return [Watir::Elements::Div] Div where form entered to create/edit entity
6
+ def form
6
7
  browser.div(class: "inlinePanel")
7
8
  end
8
9
 
@@ -27,7 +28,8 @@ module LeapSalesforce
27
28
  end
28
29
 
29
30
  # Based on data type of field passed, fill in each field
30
- # @param [Hash] data
31
+ # The type of field is attempted to be filled in based on the metadata
32
+ # @param [Hash] data Hash with label => value to set syntax.
31
33
  def populate_with(data)
32
34
  sleep 1 # Being too fast can cause issues with first value. TODO: Wait for a condition
33
35
  data.each do |desc, value|
@@ -36,28 +38,48 @@ module LeapSalesforce
36
38
 
37
39
  type = field[:type] || field["type"]
38
40
  case type
39
- when "string"
40
- set_text_field(label_name, value)
41
+ when "string" then set_text_field(label_name, value)
41
42
  when "picklist" then set_picklist(label_name, value)
42
- when "textarea"
43
- new_panel.textarea(xpath: "//label[contains(.,'#{label_name}')]//following-sibling::textarea").set value
44
- when "reference"
45
- set_reference_field(label_name, value)
43
+ when "textarea" then set_text_area(label_name, value)
44
+ when "reference" then set_reference_field(label_name, value)
46
45
  else
47
- raise NotImplementedError, "#{type} not yet defined in #{self.class}"
46
+ raise NotImplementedError, "#{type} not yet defined in #{self}"
48
47
  end
49
48
  end
50
49
  self
51
50
  end
52
51
 
53
- def set_text_field(label, value)
54
- text_field = new_panel.text_field(xpath: "//label[contains(.,'#{label}')]//following-sibling::input")
55
- text_field.focus
56
- text_field.set! value
57
- return self if text_field.value == value
52
+ # Set input text field
53
+ # @param [String] label Label of textfield
54
+ # @param [String] value Value to set textfield to
55
+ def set_text_area(label, value)
56
+ LeapSalesforce.logger.info "Setting text area, label '#{label}' with '#{value}'"
57
+ field_transaction label, value do
58
+ text_area = form.textarea(xpath: "//lightning-textarea[./label[contains(.,'#{label}')]]//following-sibling::div/textarea")
59
+ text_area.set value
60
+ end
61
+ end
58
62
 
59
- sleep 2 # Wait a bit and then set field
60
- text_field.set! value
63
+ # Set input text field
64
+ # @param [String] label Label of text field
65
+ # @param [String] value Value to set text field to
66
+ def set_text_field(label, value)
67
+ value = value.to_s
68
+ LeapSalesforce.logger.info "Setting text field, label '#{label}' with '#{value}'"
69
+ field_transaction label, value do
70
+ label_element = form.label(xpath: "//label[contains(.,'#{label}')]")
71
+ text_field = label_element.text_field(xpath: ".//following-sibling::input|.//following-sibling::div/input")
72
+ text_field.focus
73
+ text_field.set! value
74
+ return self if text_field.value == value
75
+
76
+ sleep 2 # Wait a bit and then set field
77
+ text_field.set! value
78
+ unless text_field.value == value
79
+ raise SetFieldError, "Unable to set text field '#{label}' with value " \
80
+ "'#{value}'. Value set is '#{text_field.value}'"
81
+ end
82
+ end
61
83
  self
62
84
  end
63
85
 
@@ -65,21 +87,32 @@ module LeapSalesforce
65
87
  # @param [String] label Label of picklist
66
88
  # @param [String] value Value to set picklist to
67
89
  def set_picklist(label, value)
68
- dropdown = new_panel.link(xpath: "//*[./*[text()='#{label}']]//following-sibling::div//a")
69
- dropdown.focus
70
- sleep 0.5
71
- dropdown.click
72
- browser.link(xpath: ".//div[contains(@class, 'select-options')]//a[contains(.,'#{value}')]").click
90
+ LeapSalesforce.logger.info "Setting picklist, label '#{label}' with '#{value}'"
91
+ field_transaction label, value do
92
+ dropdown = form.text_field(xpath: "//*[./*[text()='#{label}']]//following-sibling::div//input")
93
+ dropdown_id = dropdown.attribute "id"
94
+ LeapSalesforce.logger.debug "Using dropdown id: #{dropdown_id}"
95
+ dropdown.focus
96
+ sleep 0.5
97
+ dropdown.click
98
+ has_value = "@data-value='#{value}'"
99
+ in_dropdown = "starts-with(@data-item-id, '#{dropdown_id}')"
100
+ browser.element(xpath: ".//lightning-base-combobox-item[#{has_value} and #{in_dropdown}]").click
101
+ end
73
102
  self
74
103
  end
75
104
 
105
+ # Set reference field where another entity is referred to by this entity
76
106
  def set_reference_field(label, value)
77
107
  ref_label = label.gsub("ID", "Name")
78
108
  search_val = value[0..12]
79
- search_field = browser.text_field(xpath: "//label[contains(.,'#{ref_label}')]//following-sibling::div[1]//input")
80
- search_field.set search_val
81
- browser.div(xpath: "//div[contains(@data-aura-class,'forceSearchInputLookupDesktopActionItem') and contains(., 'Search')]").click
82
- browser.link(xpath: "//div[contains(@class,'searchScroller')]//a[contains(.,'#{search_val}')]").click
109
+ LeapSalesforce.logger.info "Setting reference field, label '#{ref_label}', searching with '#{search_val}'"
110
+ field_transaction label, value do
111
+ search_field = browser.text_field(xpath: "//label[contains(.,'#{ref_label}')]//following-sibling::div[1]//input")
112
+ search_field.set search_val
113
+ browser.element(xpath: ".//lightning-base-combobox-item[starts-with(.,'SearchShow')]").click
114
+ browser.link(xpath: "//div[contains(@class,'searchScroller')]//a[contains(.,'#{search_val}')]").click
115
+ end
83
116
  self
84
117
  end
85
118
 
@@ -88,20 +121,37 @@ module LeapSalesforce
88
121
  save
89
122
  end
90
123
 
124
+ # @return [Watir::Elements::Ul] List of errors
125
+ def error_list
126
+ browser.ul(xpath: "//ul[contains(@class, 'errorsList') and not(normalize-space()='')]")
127
+ end
128
+
91
129
  # Save the current form, creating the new object
92
130
  def save
93
- browser.button(title: "Save").click
94
- new_panel.wait_until do |panel|
95
- browser_list = browser.ul(class: "errorsList")
96
- if browser_list.exists?
97
- sleep 3
98
- errors = browser_list.lis
99
- sleep 1 if errors.collect(&:text) != [""] # Wait for error to come
100
- raise "Errors creating: #{errors.collect(&:text)}" if errors.count.positive?
131
+ LeapSalesforce.logger.info "Saving form for #{self}"
132
+ form.button(xpath: "//button[@title='Save']|//button[text()='Save']").click
133
+ form.wait_until do |panel|
134
+ sleep 1.5
135
+ if error_list.exists?
136
+ errors = error_list.lis
137
+ error_text = errors.collect(&:text)
138
+ LeapSalesforce.logger.error "Error submitting #{self} #{error_list.text}"
139
+ raise LeapSalesforce::SubmitError, "Errors creating on #{self}: #{error_text}" if errors.count.positive?
101
140
  end
102
141
 
103
142
  !panel.present?
104
143
  end
105
144
  end
145
+
146
+ private
147
+
148
+ # Process of setting a field within this block. Exceptions will be caught
149
+ # and thrown with context specific information
150
+ def field_transaction(label, value)
151
+ yield
152
+ rescue Watir::Exception::Error => e
153
+ raise LeapSalesforce::SetFieldError, "Unable to set label '#{label}' to '#{value}'" \
154
+ " on #{self}. Due to #{e.inspect}"
155
+ end
106
156
  end
107
157
  end
@@ -10,12 +10,16 @@ module LeapSalesforce
10
10
 
11
11
  # Create content in a file, adding to an existing file if present
12
12
  def append(filename, template_path)
13
- FileUtils.touch filename unless File.exist? filename
13
+ verb = "Appending to"
14
+ unless File.exist? filename
15
+ FileUtils.touch filename
16
+ verb = "Creating"
17
+ end
14
18
  content = read_template template_path, binding, folder: __dir__
15
19
  if File.read(filename).include?(content)
16
20
  puts "File '#{filename}' already has expected content, skipping...".colorize :red
17
21
  else
18
- puts "\u2713 Appending to #{filename}".colorize :green
22
+ puts "\u2713 #{verb} #{filename}".colorize :green
19
23
  open(filename, "a") { |f| f.puts content }
20
24
  end
21
25
  end
@@ -0,0 +1 @@
1
+ gem 'leap_salesforce_ui'
@@ -41,6 +41,7 @@ Go to #{DISABLE_2STEP_URL} to learn how to disable it"
41
41
  end
42
42
 
43
43
  def login
44
+ LeapSalesforce.logger.info "Logging in as user '#{LeapSalesforce.ui_user}'"
44
45
  browser.goto "#{LeapSalesforce.general_url}/?un=#{LeapSalesforce.ui_user}&pw=#{LeapSalesforce.password}"
45
46
  continue_button = browser.button(id: "thePage:inputForm:continue")
46
47
  if continue_button.exists?
@@ -9,7 +9,7 @@ class UpdatePage
9
9
  class << self
10
10
  def visit(id)
11
11
  LoginPage.login
12
- browser.goto "#{SoqlHandler.instance_url}/lightning/r/#{@soql_object}/#{id}/edit"
12
+ browser.goto "#{SoqlHandler.instance_url}/lightning/r/#{@soql_object.soql_object_name}/#{id}/edit"
13
13
  self
14
14
  end
15
15
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LeapSalesforceUi
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.8"
5
5
  end
@@ -7,7 +7,7 @@ class ViewPage
7
7
  class << self
8
8
  def visit(id)
9
9
  LoginPage.login
10
- browser.goto "#{SoqlHandler.instance_url}lightning/r/#{@soql_object}/#{id}/view"
10
+ browser.goto "#{SoqlHandler.instance_url}lightning/r/#{@soql_object.soql_object_name}/#{id}/view"
11
11
  self
12
12
  end
13
13
  end
@@ -4,6 +4,7 @@ require "watir"
4
4
  require "webdrivers"
5
5
  require "leap_salesforce"
6
6
  require_relative "leap_salesforce_ui/version"
7
+ require_relative "leap_salesforce_ui/error"
7
8
  require_relative "leap_salesforce_ui/base_page"
8
9
  require_relative "leap_salesforce_ui/page_introspection"
9
10
  require_relative "leap_salesforce_ui/form_filler"
@@ -32,6 +33,8 @@ end
32
33
  module LeapSalesforce
33
34
  # @return [String] User for UI
34
35
  @ui_user = nil
36
+ # @return [Boolean] Whether to run in headless mode
37
+ @headless = false
35
38
  class << self
36
39
  def browser(test_name = nil)
37
40
  @browser ||= new_browser(test_name)
@@ -42,8 +45,12 @@ module LeapSalesforce
42
45
  @browser = nil
43
46
  end
44
47
 
48
+ # @return [String] User used for UI tests
45
49
  attr_reader :ui_user
46
50
 
51
+ # @return [Boolean] Whether to run in headless mode. Default false
52
+ attr_accessor :headless
53
+
47
54
  # @param [String, Symbol, Regexp, LeapSalesforce::User] user User or email address of user
48
55
  def ui_user=(user)
49
56
  @ui_user = if user.is_a? String
@@ -61,7 +68,9 @@ module LeapSalesforce
61
68
  # TODO: Get working on Ruby 3
62
69
  Watir::Browser.new :chrome, { **zalenium_args("LeapSalesforce", test_name || "Test") }
63
70
  else
64
- Watir::Browser.new
71
+ args = {}
72
+ args[:headless] = true if headless
73
+ Watir::Browser.new :chrome, args
65
74
  end
66
75
  end
67
76
  end
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leap_salesforce_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - IQA
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-02-12 00:00:00.000000000 Z
12
+ date: 2022-01-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: leap_salesforce
@@ -29,16 +29,16 @@ dependencies:
29
29
  name: watir
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ">="
32
+ - - '='
33
33
  - !ruby/object:Gem::Version
34
- version: 6.17.0
34
+ version: '6.19'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ">="
39
+ - - '='
40
40
  - !ruby/object:Gem::Version
41
- version: 6.17.0
41
+ version: '6.19'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: webdrivers
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -87,9 +87,11 @@ files:
87
87
  - lib/leap_salesforce_ui.rb
88
88
  - lib/leap_salesforce_ui/base_page.rb
89
89
  - lib/leap_salesforce_ui/create_page.rb
90
+ - lib/leap_salesforce_ui/error.rb
90
91
  - lib/leap_salesforce_ui/form_filler.rb
91
92
  - lib/leap_salesforce_ui/generator/appenders.rb
92
93
  - lib/leap_salesforce_ui/generator/page_objects.rb
94
+ - lib/leap_salesforce_ui/generator/templates/Gemfile.erb
93
95
  - lib/leap_salesforce_ui/generator/templates/Rakefile.erb
94
96
  - lib/leap_salesforce_ui/generator/templates/create_page.rb.erb
95
97
  - lib/leap_salesforce_ui/generator/templates/spec_helper.rb.erb
@@ -126,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
128
  - !ruby/object:Gem::Version
127
129
  version: '0'
128
130
  requirements: []
129
- rubygems_version: 3.2.3
131
+ rubygems_version: 3.2.32
130
132
  signing_key:
131
133
  specification_version: 4
132
134
  summary: Helps with setting up integrated automated test frameworks against Salesforce