leap_salesforce_ui 0.1.4 → 0.1.5

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: 3481b31ac19a98f7d9fe40b017f0d9d2d047a50a891ed20e079aaee480c0c623
4
- data.tar.gz: 72ec8083bcfe9155f7e631fd5354c9d8388104bf9007985440a2518e902576f8
3
+ metadata.gz: 526d7426b4cbc68a811661af10184c81150a07d5b9f7441909758a84a6ff6353
4
+ data.tar.gz: '0248a74aeaf95af16ac34ffecac449710687283b3b27bedef3bb0814e4d95106'
5
5
  SHA512:
6
- metadata.gz: 34b181f68921877a0e0afe55fd9e4ce91f3273323065c034f8dd63e0e0b85341e1ca27187b6f8e773e25816935615c6e33baf7aab262cf65244eebfdc217de2b
7
- data.tar.gz: 9d7d119547de5453559936160ecc520e6d0db99620050c38b6297998b3f99e3e5938bb6875621bc2cdbee698c2d6e1f817743291fa15fb6c08a1435be39d2cd6
6
+ metadata.gz: 829da20fbece1a80e9e01e099d6bbdaf1d1f949670c9e91ac09d37154dd194c62fe91e9a5dd65586dc53a1597e80a3a2e0d9aa6b6fead07d61aa32cc0b051a76
7
+ data.tar.gz: 0612cb14198ae7ec1cd0200ec952661346262aefab0c746f4e4fb3ded1a4d7269bb1c925bf593ab3280dfc7c37f4ce5a261b8585f4dd11119ddc514b84602272
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,11 @@
1
+ Version 0.1.5
2
+ * Enhancements
3
+ * Added logging of actions
4
+ * Allow headless mode with LeapSalesforce.headless = true
5
+ * Throw custom errors when problem occurs setting fields
6
+ * Bug fix
7
+ * Didn't handle where class name and backend name differ
8
+
1
9
  Version 0.1.4
2
10
  * Enhancements
3
11
  * Add executable to make it fast to setup testing with exe `leap_salesforce_ui init`
@@ -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
@@ -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,47 @@ 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
+ form.textarea(xpath: "//label[contains(.,'#{label}')]//following-sibling::textarea").set value
59
+ end
60
+ end
58
61
 
59
- sleep 2 # Wait a bit and then set field
60
- text_field.set! value
62
+ # Set input text field
63
+ # @param [String] label Label of text field
64
+ # @param [String] value Value to set text field to
65
+ def set_text_field(label, value)
66
+ value = value.to_s
67
+ LeapSalesforce.logger.info "Setting text field, label '#{label}' with '#{value}'"
68
+ field_transaction label, value do
69
+ label_element = form.label(xpath: "//label[contains(.,'#{label}')]")
70
+ text_field = label_element.text_field(xpath: ".//following-sibling::input|.//following-sibling::div/input")
71
+ text_field.focus
72
+ text_field.set! value
73
+ return self if text_field.value == value
74
+
75
+ sleep 2 # Wait a bit and then set field
76
+ text_field.set! value
77
+ unless text_field.value == value
78
+ raise SetFieldError, "Unable to set text field '#{label}' with value " \
79
+ "'#{value}'. Value set is '#{text_field.value}'"
80
+ end
81
+ end
61
82
  self
62
83
  end
63
84
 
@@ -65,21 +86,28 @@ module LeapSalesforce
65
86
  # @param [String] label Label of picklist
66
87
  # @param [String] value Value to set picklist to
67
88
  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
89
+ LeapSalesforce.logger.info "Setting picklist, label '#{label}' with '#{value}'"
90
+ field_transaction label, value do
91
+ dropdown = form.link(xpath: "//*[./*[text()='#{label}']]//following-sibling::div//a")
92
+ dropdown.focus
93
+ sleep 0.5
94
+ dropdown.click
95
+ browser.link(xpath: ".//div[contains(@class, 'select-options')]//a[contains(.,'#{value}')]").click
96
+ end
73
97
  self
74
98
  end
75
99
 
100
+ # Set reference field where another entity is referred to by this entity
76
101
  def set_reference_field(label, value)
77
102
  ref_label = label.gsub("ID", "Name")
78
103
  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
104
+ LeapSalesforce.logger.info "Setting reference field, label '#{ref_label}', searching with '#{search_val}'"
105
+ field_transaction label, value do
106
+ search_field = browser.text_field(xpath: "//label[contains(.,'#{ref_label}')]//following-sibling::div[1]//input")
107
+ search_field.set search_val
108
+ browser.div(xpath: "//div[contains(@data-aura-class,'forceSearchInputLookupDesktopActionItem') and contains(., 'Search')]").click
109
+ browser.link(xpath: "//div[contains(@class,'searchScroller')]//a[contains(.,'#{search_val}')]").click
110
+ end
83
111
  self
84
112
  end
85
113
 
@@ -88,20 +116,37 @@ module LeapSalesforce
88
116
  save
89
117
  end
90
118
 
119
+ # @return [Watir::Elements::Ul] List of errors
120
+ def error_list
121
+ browser.ul(xpath: "//ul[contains(@class, 'errorsList') and not(normalize-space()='')]")
122
+ end
123
+
91
124
  # Save the current form, creating the new object
92
125
  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?
126
+ LeapSalesforce.logger.info "Saving form for #{self}"
127
+ form.button(xpath: "//button[@title='Save']|//button[text()='Save']").click
128
+ form.wait_until do |panel|
129
+ sleep 1.5
130
+ if error_list.exists?
131
+ errors = error_list.lis
132
+ error_text = errors.collect(&:text)
133
+ LeapSalesforce.logger.error "Error submitting #{self} #{error_list.text}"
134
+ raise LeapSalesforce::SubmitError, "Errors creating on #{self}: #{error_text}" if errors.count.positive?
101
135
  end
102
136
 
103
137
  !panel.present?
104
138
  end
105
139
  end
140
+
141
+ private
142
+
143
+ # Process of setting a field within this block. Exceptions will be caught
144
+ # and thrown with context specific information
145
+ def field_transaction(label, value)
146
+ yield
147
+ rescue Watir::Exception::Error => e
148
+ raise LeapSalesforce::SetFieldError, "Unable to set label '#{label}' to '#{value}'" \
149
+ " on #{self}. Due to #{e.inspect}"
150
+ end
106
151
  end
107
152
  end
@@ -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.5"
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
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.5
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: 2021-02-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: leap_salesforce
@@ -87,6 +87,7 @@ 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