Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
This gem contains the basic framework for dryly creating test scripts for the web site that needs testing.
Use it to abstract away from the underlying Watir code and create your own DSL.
With TestFactory you have the ability to...
Tremendous thanks is due to Alister Scott, whose custom page object code for the Wikimedia Foundation provided the inspiration for this gem.
Using the TestFactory properly involves three distinct steps:
These three steps can all be accomplished by a single person. However, ideally, they should be done by three or four people, as the design philosophy of TestFactory allows for specialization:
First install the gem, of course.
gem install kuali-test-factory
Now you'll want to start building your own page classes, using the methods in TestFactory as your tool chest.
Please note that the following example is very simplified and contrived, to keep every step as compartmentalized as possible. Once you've read through this, it is strongly recommended that you visit an actual repository that is using the test factory.
Here is one such.
Begin by creating a BasePage class. This class should have PageFactory as its superclass and define sets of class elements that are generally common across the pages of your site.
require 'kuali-test-factory'
class BasePage < PageFactory
class << self
def header_elements
element(:main_menu_link) { |b| b.link(title: "Main Menu") }
element(:logout) { |b| b.button(value: "Logout") }
element(:administration_link) { |b| b.link(title: "Administration") }
action(:main_menu) { |p| p.main_menu_link.click }
action(:provide_feedback) { |b| b.link(title: "Provide Feedback").click }
action(:administration) { |p| p.administration_link.click }
end
end
end
Next, you create classes for the individual pages in your web site. These classes should have BasePage as their superclass, and should declare any of the relevant methods defined in the BasePage class.
class Home < BasePage
# This allows the header elements to be defined once
# in the BasePage class and then reused throughout your web pages...
header_elements
expected_element :title # When the Home class is instantiated (using the Foundry),
# the script will ensure that the :title element is present
# on the page before the script continues
# Now you define elements that are specific to your Home page...
element(:title) { |b| b.h3(id: "title") }
# and on and on...
end
Once you've got a bunch of classes set up for your site's various pages, you're going to want to create "data objects" to represent what goes into those pages. For this, you'll use the superclass DataFactory. Your data classes should follow this basic structure:
class YourDataObject < DataFactory
# Define all the things you need to test about your data object.
# These are some example attributes...
attr_accessor :title, :id, :link, :status, :description
# Your data object has to know about Watir's browser object, so it's passed to it here, along
# with a hash containing all the attributes you want the data object to have
def initialize(browser, opts={})
@browser = browser
# Put any attributes here that you don't want to always have to define explicitly...
defaults = {
:title=>"My Data Title",
:description=>"My Data's Description"
# ...
}
# The set_options line combines the defaults
# with any options you passed explicitly in opts,
# then turns all the contents of the options
# Hash into YourDataObject's class instance variables
set_options(defaults.merge(opts))
requires :id # This line allows you to specify any class instance variables that must
# be explicitly defined for the data object
end
# Now define a bunch of methods that are relevant to your data object.
# In general these methods will follow the CRUD design pattern
def create
# Your code here...
end
def view
# Your code here...
end
def edit opts={}
# Your code here...
update_options(opts) # This updates all your class instance variables
# with any new values specified by the opts Hash.
end
def remove
# Your code here...
end
end
Now you have your basic infrastructure in place, and you can start writing your test cases using these classes.
include Foundry # Gives you access to the methods that instantiate your Page and Data classes
# First, make the data object you're going to use for testing...
@my_thing = make YourDataObject :id=>"identifier", :description=>"It's lovely."
# Now, create the data in your site...
@my_thing.create
on MyPage do |page|
page.title.set "Bla bla"
# Very contrived example. TestFactory was made to be test-framework-agnostic. You should be using your favorite verification framework here:
page.description==@my_thing.description ? puts "Passed" : puts "Failed"
end
The TestFactory was written assuming the following guiding principles. Any code that does not follow them probably smells, and should be refactored.
edit
method, first the data in the
system under test is updated, then the data object's instance variables
are updated--using DataFactory's set_options
.# During object creation, following the name of the class
@data_object = make DataObject, :attrib1 => "Custom Value 1", :attrib2 => "Custom Value 2" # etc...
# When an object is edited (using Ruby v1.9.3's Hash syntax is optional)
@data_object.edit attrib1: "Updated Value 1", attrib2: "Updated Value 2"
# This is frowned upon because it can easily lead to
# the data object and the data in the test site being
# out of sync, leading to a false negative test result:
@data_object.attrib1="Another Value"
set_options
method, not explicitly.# This is good
def edit opts={}
#...
page.element.fit opts[:value]
#...
update_options(opts)
end
# This is not good
def edit opts={}
#...
page.element.fit opts[:value]
#...
@value=opts[:value] unless @value==opts[:value]
end
#edit
method's opts
parameter. The #create
and #edit
methods will
handle the necessary logic. The purpose is to prevent the need for custom randomizing
CRUD methods in the data object.#fit
method for additional
design pattern rules to follow (If you're reading this on rubydoc.info then click the Watir module link)FAQs
Unknown package
We found that kuali-test-factory demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.