I am using Selenium, Capybara, and Rspec to write UI tests. Our project has lots of helpers and page models. I would like to sort out the helpers and page models that are only used in specific test groupings.
This is a sample of what our current project structure is like:
spec
- test grouping folder 1
- test 1
- test 2
- test grouping folder 2
- another test
- another test
- helpers
- helper 1
- helper 2
- page_models
- page 1
- page 2
- spec_helper.rb
This is what I am trying to implement:
spec
- test grouping folder 1
- helpers
- helper file 1
- page_models
- page model 1
- page model 2
- test 1 (spec file)
- test 2 (spec file)
- helpers (shared between multiple test groupings)
- page_models (shared between multiple test groupings)
- spec_helper.rb
I started by moving the relavent helper and page model files into test group 1's new helpers and page_models folders. Then in my spec helper I added the following:
require "./spec/test_group_1/helpers/helper_1"
Dir[File.dirname(__FILE__) + "spec/**/helpers/*.rb"].each { |f| require f }
Dir[File.dirname(__FILE__) + "spec/**/page_models/*.rb"].each { |f| require f }
When I run my tests I get this error:
Failure/Error: subject(:page) { PageModel1.new }
NameError:
uninitialized constant PageModel1
this is what the test looks like:
describe "TestGroup1", type: :feature do
describe "League CRUD" do
context "with an authorized user" do
subject(:page) { PageModel1.new }
before do
visit "my url here"
page.sign_in.click
login
end
it "creates a league" do
add_new_sb_page
create_league
expect(page).to have_content("League 1")
end
end
end
end
This is what my page_model looks like:
class PageModel1 < SitePrism::Page
element :example, "div#example"
end
Why would changing the structure cause this error? Is there a better way to structure my project?
Related
I am new to using PageObject::PageFactory.
I can’t get this simple scenario to work. Can someone Help me with this?
My Feature file
Feature: Find Pens
Scenario:
Given a user goes to Amazon website
When they search for “pens”
Then they are able to find “pens”
My Step_definition
Given(/^a user goes to Amazon website$/) do
visit HomePage
end
When(/^they search for “(.*?)”$/) do |page|
on HomePage do
page.look_pens
end
end
Then(/^they are able to find “(.*?)”$/) do |arg1|
pending # express the regexp above with the code you wish you had
end
Page Object file
QUESTION: Is it right to put this file in Support folder or should this be living elsewhere?
class HomePage
include PageObject
page_url(‘http://www.amazon.co.uk’)
text_field(:name, :id=> ‘twotabsearchtextbox’) #:id is the web-element from the actual webpage. Should this be something else?
button(:search, :value=>’Go’)
def look_pens(name,search)
self.name = pens
self.search
end
end
The Given part when run with Cucumber-SeleniumWebdriver does open the Amazon browser, but after that gives the following error for the When part
The Error
p.rb:1
When they search for “pens” # features/step_definitions/buy_pens_ste
p.rb:5
undefined method `look_pens’ for “pens”:String (NoMethodError)
./features/step_definitions/buy_pens_step.rb:7:in `block (2 levels) in ‘
./features/step_definitions/buy_pens_step.rb:6:in `/^they search for “(.*?
)”$/’
features\buy_pens.feature:5:in `When they search for “pens”‘
My env.rb in the support folder contains:
require ‘page-object’
require ‘selenium-webdriver’
require ‘page-object/page_factory’
Before do
#browser = Selenium::WebDriver.for(:firefox)
end
After do
#browser.close
end
World(PageObject::PageFactory)
Typically page object files are maintained in a separate folder that is at the same level as the features directory. You will need to use additional require statements so that Ruby knows that they are located in that folder.
Re the error: Looks like the compiler is having difficulty recognizing that look_pens is a method of the HomePage class. Try moving the |page| from the end of the When step def to the second line, so that it looks like code below.
When(/^they search for “(.*?)”$/) do
on HomePage do |page|
page.look_pens
end
end
I have this problem with my code.This page inside my application is using http basic authentication. I'm testing my application with Rspec and Capybara, but I have problem with data confirmation when deleting comment, it just can't seem to pass.
Here is my test code:
before(:each) do
page.driver.browser.authorize ENV['ADMIN_LOGIN'], ENV['ADMIN_PASSWORD']
...
end
...
it "should redirect to create new inspiring post and create new post on click" do
visit admin_path
click_link("create_inspi")
fill_in("Title",:with => "Test title")
fill_in("Short",:with => "Test short desc")
fill_in("Body",:with => "Test body desc")
fill_in("Date",:with => "12.12.2012")
click_button("Create new post")
test(
have_content("Test title"),
have_content("12.12.2012")
)
end
example "when inside Link to all... you can delete particular comment",:js => true do
visit admin_path
click_link("Link to all comments in Web development and Motivation category")
click_link(#webdev_comment.id)
page.driver.browser.accept_js_confirms
end
Now for my test by default I use Capybara::RackTest::Driver, but now since I can't find a way to confirm data confirmation with RackTest I have to use Selenium driver to make this data confirmed. But now when using this Selenium driver for my last example test I found next problem:
1) testing admin webpage when inside Link to all... you can delete particular comment
Failure/Error: page.driver.browser.authorize ENV['ADMIN_LOGIN'], ENV['ADMIN_PASSWORD']
NoMethodError:
undefined method `authorize' for #<Selenium::WebDriver::Driver:0x00000003e6ad68>
# ./spec/features/admin.rb:13:in `block (2 levels) in <top (required)>'
MY QUESTION IS:
How to authenticate basic http with selenium?
-------------- EDITED ------------------
I found a way to log in into admin with selenium driver by using this code
example "when inside Link to all... you can delete particular comment",:js => true do
visit root_path
#url = current_url
#tablica = #url.split("http://")
#correct_url = #tablica[1]
admin_selenium_path = "http://#{ENV["ADMIN_LOGIN"]}:#{ENV["ADMIN_PASSWORD"]}##{#correct_url}admin"
page.visit admin_selenium_path
click_link("Link to all comments in Web development and Motivation category")
click_link(#webdev_comment.id)
page.driver.browser.accept_js_confirms
end
But now , even though it's logging in , there is literally no data inside test database, and it's throwing errors around saying that particular object couldn't be found.
before(:each) do
# page.driver.browser.authorize ENV['ADMIN_LOGIN'], ENV['ADMIN_PASSWORD']
#mystory = Mystory.create(name: "My story:",body: "My name is Matthew...")
end
This code above inside before block is not creating a required #mystory record inside database for capybara with selenium driver.
Any ideas how to populate database for capybara with selenium driver?
I'm not sure if it's exactly the same issue but I add this somewhere above/before to skip over confirm dialogs with Capybara
page.evaluate_script('window.confirm = function() { return true; }')
I'm trying to do test-driven development in typo3 4.7.8, a PHP based CMS.
Using the TestingFramework class provided by the phpunit extension, I have problems following the tutorial documentation provided with the phpunit extension (regarding the TestingFramework class)
Here I have this trivial unit test
/**
* #test
*
*/
public function fake_frontend_can_be_instantiated() {
$this->testingFramework->createFakeFrontEnd(16); // uid=16
$expectedResult = 1;
$actualResult = $this->testingFramework->hasFakeFrontEnd();
$this->assertEquals ( $expectedResult, $actualResult );
}
Result:
fake frontend can be instantiated
! Error in test case fake_frontend_can_be_instantiated
File: .../typo3_src-4.7.8/t3lib/class.t3lib_db.php
Line: 730
mysql_real_escape_string() expects parameter 2 to be resource, integer given
The same happens when I call createFakeFrontEnd() with empty args.
When I enable the dbal extension (database abstraction layer) this is the output:
File: ...typo3-4.7.8/typo3_src-4.7.8/typo3/sysext/dbal/class.ux_t3lib_db.php
Line: 1546
mysql_query() expects parameter 2 to be resource, integer given
I really like to use the TestingFramework, because I have a whole lot of frontend users to create,, and I want to test each user's login credentials before we send out notification emails.
I want to define a function available_translations which lists the translations I have made for my application into the I18n module.
I tried putting the following into the file lib/i18n.rb, but it doesn't work when I try to use it from the rails console:
module I18n
# Return the translations available for this application.
def self.available_translations
languages = []
Dir.glob(Rails.root.to_s + '/config/locales/*.yml') do |filename|
if md = filename.match #^.+/(\w+).yml$#
languages << md[1]
end
end
languages
end
end
Console:
ruby-1.9.2-p290 :003 > require Rails.root.to_s + '/lib/i18n.rb'
=> false
ruby-1.9.2-p290 :004 > I18n.available_translations
NoMethodError: undefined method `available_translations' for I18n:Module
...
Besides solving my concrete problem, I would be very pleased to learn how this whole module thing in Ruby on Rails works because it still confuses me, so I would appreciate links to the docs or source code very much.
Either of these will solve your problem:
move the code to config/initializers/i18n.rb, or
require your file from config/application.rb, or
name your class otherwise (to trigger autoload)
The code in lib/i18n.rb wil not be loaded by autoload since I18n name will be already loaded, so either you load it yourself or change the class name (and file name) so the new name will trigger autoload behavior.
BTW, the I18n.available_locales() method is presented in rails.
I'm following the Ruby on Rails 3 tutorial, chapter 6. Inside my directory spec/models/user_spec.rb, i have a 6 test cases (no need to rly read them):
require 'spec_helper'
describe User do
#pending "add some examples to (or delete) #{__FILE__}"
before(:each) do
#attr = { :name => "Example User", :email => "user#example.com"}
end
it "should creat a new instance given valid attributes" do
User.create!(#attr)
end
.
.
.
it "should reject invalid email addresses" do
addresses = %w[user#foo,com user_at_foo.org example.user#foo.]
addresses.each do |address|
invalid_email_user = User.new(#attr.merge(:email => address))
invalid_email_user.should_not be_valid
end
end
end
In the console, i type $ rspec spec/models/user_spec.rb and it spits out
No DRb server is running. Running in local process instead ...
*
Pending:
User add some examples to (or delete) /Users/matthew/Desktop/rails_projects/sample_app/spec/models/user_spec.rb
# Not Yet Implemented
# ./spec/models/user_spec.rb:4
Finished in 0.00023 seconds
1 example, 0 failures, 1 pending
The last line says i only have 1 example and 1 pending, but i've written 6 tests! This inconsistency boggles my mind! No syntax errors, i'm saving the file, i'm in the right directory, etc.
By far the strangest thing (i'm using Mac OS X and Textmate):
Despite correct code, directory, etc. CMD+S or File-> Save was not saving the files at all. I've been opening the files via command line. Solution is to just close the shell and open a new one.