Skip to content

Gxt PageObject widget example

December 27, 2012

I have provided an example for adding widgets to page-object below.  In this example, I have created a test widget to interact with the gxt pagination tool on the gxt examples page.

This widget is typical of widgets created in day-to-day use.  It defines several methods which identify and act on elements using the ‘nested element’ methods built into page-object.

Widgets such as this one typically rely on the fact that each object will be in a predictable location relative to a main table or div. This widget relies on a defined table with fixed indexes to find the correct buttons.

class GxtPager < PageObject::Elements::Div

  def first
    first_cell = cell_elements(:class=>"x-toolbar-cell")[0]
    first_cell.button_element(:tag_name=>"button").click
  end

  def previous
    next_cell = cell_elements(:class=>"x-toolbar-cell")[1]
    next_cell.button_element(:tag_name=>"button").click
  end

  def last
    next_cell = cell_elements(:class=>"x-toolbar-cell")[8]
    next_cell.button_element(:tag_name=>"button").click
  end

  def next
    next_cell = cell_elements(:class=>"x-toolbar-cell")[7]
    next_cell.button_element(:tag_name=>"button").click
  end

  def page
    page_cell = cell_elements(:class=>"x-toolbar-cell")[4]
    page_cell.text_field_element.value
  end

  def page=(page_number)
    page_cell = cell_elements(:class=>"x-toolbar-cell")[4]
    page_cell.text_field_element.value=page_number
    page_cell.text_field_element.send_keys :return
  end
end
PageObject.register_widget :gxt_pager, GxtPager, 'table'

Below you’ll see the use of the widget within a page-object. I’ve gotten into the habit of registering widgets at the bottom of the defining class, then requiring that class where it needs to be used.

require_relative 'widgets/gxt_grid'
require_relative 'widgets/gxt_pager'

class GxtSamplePageObject
  include PageObject

  div(:basic_grid, :class => "label_basic_grid")
  div(:local_pagination, :class => "label_paging_grid")
  gxt_table(:gxt_table, :class => "x-grid3")
  gxt_pager(:gxt_pager, :class =>"x-toolbar-ct")
end

Just to make sure everything is covered, I have included the step definitions which use this class below. See previous blog posts or the page-object wiki for the gxt_table code used here.

Given /^I am on the Gxt Examples page$/ do
  @page = GxtSamplePageObject.new(@browser)
  @page.navigate_to "http://gxtexamplegallery.appspot.com/"
end

When /^I have Local Pagination open$/ do
  @page.local_pagination_element.click
end

When /^I click next page$/ do
  @page.gxt_pager_element.next
end

Then /^I should be on page "(\d+)"$/ do |page_expected|
  @page.gxt_pager_element.page.should == page_expected
end

When /^"([^"]*)" should be listed in the grid$/ do |name_expected|
  @page.gxt_table_element[1][0].text.should == name_expected
end

When /^I click last page$/ do
  @page.gxt_pager_element.last
end

When /^I click on previous page$/ do
  @page.gxt_pager_element.previous
end

When /^I click on first page$/ do
  @page.gxt_pager_element.first
end

When /^type "(\d+)" into the page box$/ do |page|
  @page.gxt_pager_element.page=page
end
10 Comments
  1. Tyler Thrailkill permalink

    I’m trying to write a Widget for a GWT MutableDataGrid table. I’ve got a class:

    class WorklistTable ‘0’)
    end

    protected

    def column_name
    @column_row = table(:column_table, :index => 0)
    end

    def child_xpath
    “.//descendant::tr”
    end
    end

    PageObject.register_widget :worklist_table, WorklistTable, :div

    But I’m getting errors telling me that table is deprecated. I can’t find any good documentation on what namespace we are supposed to extend either.

  2. Tyler Thrailkill permalink

    Hmm that didn’t format correctly.
    class WorklistTable ‘0’)
    end

  3. Tyler Thrailkill permalink

    class WorklistTable < PageObject::Elements::Div

    def find_patient index
    table(:column_table, :index => ‘0’)

  4. it looks like the only real error is the use of ‘table’ instead of ‘table_element’. You might want to pull my gxt-widgets library on github: https://github.com/wjpowell/gxt-widgets Extending the table turned out to be pretty tricky because of how the page-object table looks up rows and columns by name. The gxt-widgets table contains a working table, and can serve as an example for adding the functionality that you need for your MutableDataGrid.

    • Tyler Thrailkill permalink

      I’m still having a ton of trouble figuring out how to format the code. So say I have a page

      > class WorklistPage
      > include PageObject
      > worklist_table(:a_table, :id => “worklist_grid”)
      > end

      and I need to create a widget for this (http://pastebin.com/uMd6WtSA) bit of html. It’s a GWT DataGrid that’s been slightly modified for our company in order to make the column headers movable. I put it in a pastebin because it’s kind of long and I wanted to make sure you could see the whole thing.

      So as you can see I have an id on the lowest element of the table :id => “worklist_grid”
      Now I want to be able to do pretty much exactly what you do with the gxt-widgets gem. I tried reading through all the specs and features, but I can’t get what you’re doing to work for me. I mostly don’t understand it.

      I’ve created this WorklistTable class to try and just access the first table in the html, which is where the headers are, but I can’t get it to find any elements.

      > class WorklistTable < PageObject::Elements::Table

      > def find_header
      > t = table_element(:a_name, :index => ‘0’)
      > end

      > end
      > PageObject.register_widget :worklist_table, WorklistTable, :div

      say I try to find just the whole table. I have a WorklistPage instance called worklist and I call:

      > worklist.a_table_element

      It returns the object as not being found:
      => #<Watir::Div:0x94191b0 located=false selector={:id=>”worklist_grid”, :tag_name=>”div”}>
      even though I’ve given it the id and it looks semantically correct.

      if I try to call the find_header method on that object I get this error.
      NoMethodError: undefined method `delete’ for :a_name:Symbol
      from C:/Ruby193/lib/ruby/gems/1.9.1/gems/page-object-0.8.9/lib/page-object/platforms/watir_webdriver/page_object.rb:982:in `parse_identifiers’
      from C:/Ruby193/lib/ruby/gems/1.9.1/gems/page-object-0.8.9/lib/page-object/platforms/watir_webdriver/page_object.rb:966:in `find_watir_element’
      from C:/Ruby193/lib/ruby/gems/1.9.1/gems/page-object-0.8.9/lib/page-object/platforms/watir_webdriver/page_object.rb:497:in `table_for’
      from C:/Ruby193/lib/ruby/gems/1.9.1/gems/page-object-0.8.9/lib/page-object/locator_generator.rb:37:in `block (2 levels) in generate_locators’
      from C:/Recondo/projects/portal/acceptance_driven_testing/watir/lib/pages/worklist/worklist_table.rb:5:in `find_header’
      from (irb):8
      from C:/Ruby193/bin/irb:12:in `*lt;main>’

      It seems that that error is because I gave the table_element a name. So if I remove the name then I just get this error:
      => #<Watir::Table:0x..f88c30aa0 located=false selector={:index=>”0″, :tag_name=>”table”}>

      I literally have no clue how this widget this is supposed to work now. If you could help me out it would be much appreciated.

      • the widget and the find_header method within it look fine. Are you sure that you’re on the correct page when you try to identify the table?

        The Watir element not found error should be your initial focus, since the locator it’s using should find the element on the html page that you provided.

  5. Tyler Thrailkill permalink

    Ah ok, I’ll try this later and update on how it goes.

  6. Tyler Thrailkill permalink

    Yeah I’m absolutely sure I’m on the page when running this code..

  7. Tyler Thrailkill permalink

    Ok I’ve finally gotten it to work. What I did was just replicate the files from your gxt gem. I actually don’t even know if that was necessary, because the files I have seem to work just fine with the tables I have. I am trying to add methods like you have in the modules folder. Some of the methods I’m trying to add include things to check that certain rows contain certain values, etc. Maybe click on those rows. I can’t really figure out how to add these methods. Is there any way you can add a bit more information to the gxt-widgets wiki explaining the principles etc?

  8. Tyler Thrailkill permalink

    Ok after rereading over what I wrote above I realize I wasn’t very clear.
    I would like to be able to write a method to click on a button in a certain row. Where would I put a method like this and how would I make it check certain cells (by column name) in each row?

Leave a comment