Skip to content

Instantly share code, notes, and snippets.

@Castone22
Created January 28, 2019 18:53
Show Gist options
  • Save Castone22/f6da29e54d4b70d5d29da509e1233619 to your computer and use it in GitHub Desktop.
Save Castone22/f6da29e54d4b70d5d29da509e1233619 to your computer and use it in GitHub Desktop.
class CoreElement;
end
require_all('./elements')
class CoreElement
def self.type
:core_element
end
@@locator_options = [:id, :class, :xpath, :text, :href, :for, :name]
def self.locator_options
@@locator_options
end
attr_reader :name, :active, :locator_hash, :type
### Attrib Methods ###
def initialize(name, world, options)
@type = self.class.type
@name = name + self.class.type
has_locator = false
@@locator_options.each do |locator_type|
if options[locator_type]
@locator_hash = {locator_type => options[locator_type]}
has_locator = true
end
end
raise "ELEMENT [#{name}] must have a locator!/nValid locators are: #{@@locator_options}" unless has_locator
@world = world
@options = {:active => true}.merge(options)
@active = @options[:active]
assign_element_type
end
def browser
@world.browser
end
def parent
@options[:parent] ? @options[:parent].watir_element : browser
end
def watir_element
@watir_element ||= parent.send(@element_type, @locator_hash)
end
def assign_element_type
@element_type = @options[:element_type] ? @options[:element_type] : :div
end
### Behavioral Methods ###
def click
assert_active
@world.logger.action "Clicking [#{@name}]"
begin
watir_element.click
rescue Selenium::WebDriver::Error::UnknownError => e
raise e unless e.message =~ /Element is not clickable at point .* Other element would receive the click/
@world.logger.warn 'Click failed, assuming it was due to animations on the page. Trying again...'
raise "Click kept failing! Original Error: \n#{e}" unless CoreUtils.wait_safely(3){ watir_element.click }
end
@on_click.call if @on_click
end
def on_click(&block)
@on_click = block
end
def hover
assert_active
@world.logger.action "Hovering over [#{@name}]"
begin
watir_element.hover
rescue Watir::Exception::UnknownObjectException => e
@world.logger.warn 'Unable to hover over element, attempting to proceed anyway...'
return false
end
@on_hover.call if @on_hover
end
def on_hover(&block)
@on_hover = block
end
def fill(data)
@on_fill.call if @on_fill
end
def on_fill(&block)
@on_fill = block
end
def visible?
@world.logger.warn '[OZ DEPRECATION] Checking `#visisble?` is deprecated. Use `#present?` instead.'
present?
end
def present?
watir_element.present?
end
def flash
return unless @world.configuration['FLASH_VALIDATION']
assert_active
watir_element.flash
end
def value
assert_active
return nil unless present?
watir_element.text
end
def attribute_value(attribute_name)
watir_element.attribute_value(attribute_name)
end
def assert_active
raise "ERROR: Element [#{@name}] being accessed when not active!!\n" unless @active
end
def activate
@active = true
end
def deactivate
@active = false
end
def active?
@active
end
def activate_if(condition)
condition ? activate : deactivate
end
def validate(data)
status = active ? 'is' : 'is not'
validation_point = @world.validation_engine.add_validation_point("Checking that [#{@name}] #{status} displayed...")
Selenium::WebDriver.logger.level = :debug
Watir.logger.level = :debug
if active == present?
validation_point.pass
flash if active
elsif !active && present?
validation_point.fail(" [#{@name}] was found on the page!\n FOUND: #{@name}\n EXPECTED: Element should not be displayed!")
else
validation_point.fail(" [#{@name}] was not found on the page!\n FOUND: None\n EXPECTED: #{@name} should be displayed!")
end
Selenium::WebDriver.logger.level = :info
Watir.logger.level = :info
end
end
# CorePage will be the basis for all other pages we create,
# there should be an instance of this page saved in the @world object upon each scenario's creation.
# Eventually this page will become the recorder/basis for how we will record interactions with the DB and others.
class CorePage
### Setup ###
#############
def initialize(world, root_page=false)
@world = world
@ledger = @world.ledger
unless root_page
@elements = {}
create_common_elements
create_elements
end
end
### Step Definition Methods ###
###############################
def fill(data_name=nil)
data_name ||= @world.data_target
data = input_data(data_name)
raise ArgumentError, "ERROR: Method: [input_data] of class [#{self.class}] should return a Hash\n" unless data.class == Hash
data.each_key do |element_name|
raise "Element: {#{element_name}} in data set does not exist on the page!" unless @elements.keys.include?(element_name)
@elements[element_name].fill(data[element_name])
end
end
def click_on(element_name)
@elements[element_name].click
end
def hover_over(element_name)
@elements[element_name].hover
end
def validate_content
data = expected_data()
raise ArgumentError, "ERROR: Method: [expected_data] of class [#{self.class}] should return a Hash\n" unless data.class == Hash
@world.validation_engine.enter_validation_mode
@elements.values.each do |element|
element.validate(data[element.name])
end
@world.validation_engine.exit_validation_mode
end
### Data ###
############
def input_data(data_name)
@world.data_engine.get_input_data(yml_file, data_name)
end
def expected_data(data_name = "DEFAULT")
@world.data_engine.get_expected_data(yml_file, data_name)
end
def yml_file
#The extra long gunk here basically just looks for the file that has the 'create_elements' method defined inside it and replaces the .rb extension with .yml
self.class.instance_method(:create_elements).source_location.first.gsub(/\.rb$/,".yml")
end
def browser
@world.browser
end
end
Given /^I have (.*)$/ do |target|
set_data_target(target.gsub(' ', '_').upcase)
end
Given /^I am on the (.*?) Page(?: by way of the (.*?) Page)?$/ do |target_page, intermediate_page|
@root_page.begin_new_session
proceed_to(CoreUtils.find_class(intermediate_page+' Page')) if intermediate_page
proceed_to(CoreUtils.find_class(target_page+' Page'))
set_data_target
end
When /^I (?:proceed|go back) to the (.*?) Page(?: by way of the (.*?) Page)?$/ do |target_page, intermediate_page|
proceed_to(CoreUtils.find_class(intermediate_page+' Page')) if intermediate_page
proceed_to(CoreUtils.find_class(target_page+' Page'))
set_data_target
end
When /^I fill the page with (.*)$/ do |data_name|
@current_page.fill(data_name)
end
When /^I click the (.*)$/ do |element_name|
@current_page.click_on(element_name.gsub(' ','_').downcase.to_sym)
end
When /^I hover over the (.*)$/ do |element_name|
@current_page.hover_over(element_name.gsub(' ','_').downcase.to_sym)
end
### CORE Validation Steps ###
#############################
#Tags: @static_text
# Checks all of the static_text objects on the page to make sure they are present and contain the proper text.
# The data used for checking is defined in the page class and/or in the page class's .yml file.
Then /^I can see that all the content on the page is correct$/ do
@current_page.validate_content
end
#Tags: @navigation
# Checks that the application is on the specified page.
Then /^I should see the (.*) Page$/ do |page|
page_class = CoreUtils.find_class(page+' Page')
validate_application_is_on_page(page_class)
end
Feature: New Account Page
Scenario: Filling out the new account page should cause
Given I am on the New Account Page
When I fill the page with Input Test
Then I can see that all the content on the page is correct
@Castone22
Copy link
Author

[ VALIDATE ]-> Checking that company_name_text_field is displayed...
2019-01-28 13:26:39 INFO Selenium -> GET session/d3b5ef70fa86fca92a0788d3a3e55d37/element/0.9450179996584991-9/displayed
2019-01-28 13:26:39 INFO Selenium <- {"sessionId":"d3b5ef70fa86fca92a0788d3a3e55d37","status":10,"value":{"message":"stale element reference: element is not attached to the page document\n  (Session info: chrome=71.0.3578.98)\n  (Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.16299 x86_64)"}}
2019-01-28 13:56:29 INFO Selenium -> POST session/d3b5ef70fa86fca92a0788d3a3e55d37/elements
2019-01-28 13:56:29 INFO Selenium    >>> http://127.0.0.1:9516/session/d3b5ef70fa86fca92a0788d3a3e55d37/elements | {"using":"xpath","value":".//*[local-name()='input'][not(@type) or (translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='file' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='radio' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='checkbox' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='submit' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='reset' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='image' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='button' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='hidden' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='range' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='color' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='date' and translate(@type,'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ','abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ')!='datetime-local')][contains(@name, '-Name')]"}
2019-01-28 13:56:29 DEBUG Selenium      > {"Accept"=>"application/json", "Content-Type"=>"application/json; charset=UTF-8", "User-Agent"=>"selenium/3.141.0 (ruby windows)", "Content-Length"=>"2794"}
2019-01-28 13:56:29 INFO Selenium <- {"sessionId":"d3b5ef70fa86fca92a0788d3a3e55d37","status":0,"value":[{"ELEMENT":"0.9450179996584991-24"}]}
2019-01-28 13:56:29 DEBUG Watir Iterating through 1 elements to locate {:name=>/-Name$/, :tag_name=>"input"}
2019-01-28 13:56:29 INFO Selenium -> GET session/d3b5ef70fa86fca92a0788d3a3e55d37/element/0.9450179996584991-24/name
2019-01-28 13:56:29 INFO Selenium <- {"sessionId":"d3b5ef70fa86fca92a0788d3a3e55d37","status":0,"value":"input"}
2019-01-28 13:56:29 INFO Selenium -> GET session/d3b5ef70fa86fca92a0788d3a3e55d37/element/0.9450179996584991-24/attribute/name
2019-01-28 13:56:29 INFO Selenium <- {"sessionId":"d3b5ef70fa86fca92a0788d3a3e55d37","status":0,"value":"NewAccount-NewAccountScreen-NewAccountSearchDV-GlobalContactNameInputSet-Name"}
2019-01-28 13:56:29 INFO Selenium -> GET session/d3b5ef70fa86fca92a0788d3a3e55d37/element/0.9450179996584991-24/displayed
2019-01-28 13:56:29 INFO Selenium <- {"sessionId":"d3b5ef70fa86fca92a0788d3a3e55d37","status":0,"value":true}
2019-01-28 13:56:29 WARN Watir [DEPRECATION] ["stale_present"] Checking `#present? == false` to determine a stale element is deprecated. Use `#stale? == true` instead; see explanation for this deprecation: http://watir.com/staleness-changes.
[ VALIDATE ]->   company_name_text_field was not found on the page!
       FOUND: None
    EXPECTED: company_name_text_field should be displayed!
[ VALIDATE ]-> Checking that company_name_text_field contains Test...
2019-01-28 13:56:29 INFO Selenium -> GET session/d3b5ef70fa86fca92a0788d3a3e55d37/element/0.9450179996584991-24/attribute/value
2019-01-28 13:56:29 INFO Selenium <- {"sessionId":"d3b5ef70fa86fca92a0788d3a3e55d37","status":0,"value":"Test"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment