# encoding: utf-8 require File.expand_path('../watirspec_helper', __FILE__) describe 'Collection' do before :each do browser.url = fixture('non_control_elements.html') @collection = window.find_by_tag(:div) end # elements describe '#find_by_id' do it 'returns an element with the given ID' do elements = @collection.find_by_id('header') elements.should_not be_empty elements.length.should == 1 elements.first.attr(:id).should == 'header' end it 'finds multiple elements with the same id' do elements = @collection.find_by_id('lead') elements.length.should == 4 end end describe '#find_by_tag' do it 'is not empty if the tag exists under the collection' do @collection.find_by_tag(:a).should_not be_empty end it 'contains all elements of the tag name under the collection' do as = @collection.find_by_tag(:a) as.length.should == 4 as.all? do |element| element.tag_name.should match /a/i end.should be_true end it 'contains only elements restricted by the selector' do @collection.find_by_tag(:span, :title => 'Lorem ipsum').all? do |element| element.attr(:title) == 'Lorem ipsum' end.should be_true end it 'is empty if the elements do not exist' do @collection.find_by_tag(:hoobaflooba).should be_empty end end # css # we don't want a complete CSS selector test suite here, so just some common # selectors describe '#find_by_css' do it 'is not empty if an element matches the css selector' do @collection.find_by_css('ul').should_not be_empty end it 'contains all elements selected by the selector' do collection = window.find_by_id('outer_container') divs = collection.find_by_css('div') divs.length.should == 7 divs[1].id.should == 'promo' divs[3].id.should == 'best_language' divs[6].id.should == 'hidden' end it 'is empty if the selector does not match' do @collection.find_by_css('#hoobaflooba').should be_empty end end # class describe '#find_by_class' do it 'is not empty if an element matches the class' do @collection.find_by_class(:lead).should_not be_empty end it 'contains all elements with the given class' do collection = window.find_by_id('promo') leads = @collection.find_by_class(:lead) leads.length.should == 4 leads.all? do |element| element.attr(:class).should match /lead/ end.should be_true end it 'finds elements with multiple classes' do collection = window.find_by_id('header') collection.find_by_class(:one).all? do |element| element.attr(:class).should match /one/ end.should be_true end it 'is empty if the class does not match' do @collection.find_by_class(:hoobaflooba).should be_empty end end # xpath describe '#find_by_xpath' do before :each do @headers = @collection.find_by_xpath('//h1') end it 'is not empty if elements matches the class' do @headers.should_not be_empty end it 'contains all elements with the given query' do @headers.all? do |element| element.tag_name.should match /h1/i end end it 'is empty if the query does not match' do @collection.find_by_xpath('//hoobaflooba').should be_empty end it 'finds elements in the current context' do subdivs = @collection.find_by_xpath('div') subdivs.length.should == 7 # XPath spec says order not guaranteed, so just check they're here ids = subdivs.map { |el| el.id } ids.should include 'promo' ids.should include 'best_language' ids.should include 'hidden' end end # sugar describe 'syntactic sugar' do it 'returns all descendants with the given tag' do window.find_by_id('promo').span.length.should == 5 end it 'can be chained' do lis = window.find_by_id('promo').ul.li lis[0].text.should == 'Abietic acid, C20H30O2' lis[2].text.should == 'Acenaphthoquinone, C12H6O2' lis[4].text.should == 'Acetaldehyde (ethanal), CH3CHO' end it 'can be chained deeply' do window.body.div.div.ul.li.a.id.should == [nil, 'link_2', 'link_3'] end it 'returns the same as #find_by_tag' do @collection.span(:title => 'Lorem ipsum').should == @collection.find_by_tag(:span, :title => 'Lorem ipsum') end # This may be unnecessary... it 'responds to html elements' do [:a,:abbr,:address,:area,:article,:aside,:audio,:b,:base,:bdo,:blockquote,:body, :br,:button,:canvas,:caption,:cite,:code,:col,:colgroup,:command,:datalist,:dd, :del,:details,:dfn,:div,:dl,:dt,:em,:embed,:eventsource,:fieldset,:figcaption, :figure,:footer,:form,:h1,:h2,:h3,:h4,:h5,:h6,:head,:header,:hgroup,:hr,:i, :iframe,:img,:input,:ins,:kbd,:keygen,:label,:legend,:li,:link,:mark,:map, :menu,:meta,:meter,:nav,:noscript,:object,:ol,:optgroup,:option,:output,:p, :param,:pre,:progress,:q,:ruby,:rp,:rt,:samp,:script,:section,:select,:small, :source,:span,:strong,:style,:sub,:summary,:sup,:table,:tbody,:td,:textarea, :tfoot,:th,:thead,:time,:title,:tr,:ul,:var,:video,:wbr].all? do |symbol| @collection.respond_to? symbol end.should be_true end end # length describe '#length' do it 'is the number of items in the collection' do @collection.length.should == 12 end end # item access describe '#[]' do it 'accesses the elements in the collection' do @collection[5].attr(:id).should == "best_language" @collection[@collection.length-1].attr(:id).should == "del_tag_test" end end describe '#attr' do it 'returns the given attribute of the first element' do collection = window.find_by_class('external') collection.attr(:id).should == 'link_2' end end # attrs(what) describe 'attrs' do it 'returns the attributes of each of the elements in the collection' do @collection.attrs(:id)[1].should == 'outer_container' @collection.attrs(:id)[2].should == 'header' @collection.attrs(:id)[9].should == 'messages' end end # id describe '#id' do it 'is the id attribute if there is one element' do window.find_by_class("primary").id.should == "first_header" end it 'is nil if the single element has no id' do window.find_by_class("php").id.should == nil end it 'is an array of ids if there is more than one element' do window.find_by_class("external").id.should == ["link_2", "link_3"] end end # class # TODO this is the class attribute, so it could have multiple classes, in # which case this name doesn't make much sense describe '#class_name' do it 'is the class attribute if there in one element' do window.find_by_id("favorite_compounds").class_name.should == "chemistry" end it 'is nil if the single element has no class' do window.find_by_id("outer_container").class_name.should == nil end it 'is an array of class attributes if there is more than one element' do window.find_by_class('external').class_name.should == [ 'external one two', 'external' ] end it 'is an array with nil elements when the elements have no class' do window.find_by_tag("a").class_name.should == [ nil, 'external one two', 'external', nil ] end end describe '#tag_name' do it 'is the tag name if there is one element' do window.find_by_id('header4').tag_name.should == 'H4' end it 'is an array if there are more than one elements' do window.find_by_class('lead').tag_name.should == ['SPAN', 'P', 'INS', 'DEL'] end end # states # ------ describe '#click' do it 'clicks all the elements in this collection' do collection = window.find_by_class('footer') collection.click collection.all? do |element| element.text.match(/Javascript/) != nil end.should be_true end end # checked? describe '#checked?' do before :each do browser.url = fixture('forms_with_input_elements.html') @boxes = window.find_by_tag(:input, :type => 'checkbox') end it 'is true if all of the elements are checked' do @boxes.each do |box| box.check! end @boxes.checked?.should be_true end it 'is false if one of the elements is not checked' do @boxes.checked?.should be_false end end # check! describe '#check!' do it 'checks all of the checkboxes' do browser.url = fixture('forms_with_input_elements.html') @boxes = window.find_by_tag(:input, :type => 'checkbox') @boxes.check! @boxes.all? do |box| box.checked? == true end.should be_true end end # uncheck! describe '#uncheck!' do it 'unchecks all of the checkboxes' do browser.url = fixture('forms_with_input_elements.html') @boxes = window.find_by_tag(:input, :type => 'checkbox') @boxes.uncheck! @boxes.all? do |box| box.checked? == false end.should be_true end end # toggle_check! describe '#toggle_check!' do it 'toggles the checked state of all of the checkboxes' do browser.url = fixture('forms_with_input_elements.html') @boxes = window.find_by_tag(:input, :type => 'checkbox') # Store the initial values values = @boxes.map { |el| el.checked? } @boxes.toggle_check! # Check they've all changed (0..values.size-1).all do |i| @boxes[i].checked? == !values[i] end.should be_true end end # enabled? describe '#enabled?' do before :each do browser.url = fixture('forms_with_input_elements.html') end it 'returns true if all collection elements are enabled' do window.find_by_id('delete_user').fieldset.first.option.enabled? should be_true end it 'returns false if any collection elements are disabled' do window.find_by_id('new_user').input.enabled?.should be_false end end # enable! describe '#enable!' do it 'enables all elements in the collection' do browser.url = fixture('forms_with_input_elements.html') window.find_by_id('new_user').input.enable! window.find_by_id('new_user_species').first.enabled?.should be_true end end # disable! describe '#disable!' do it 'disables all elements in the collection' do browser.url = fixture('forms_with_input_elements.html') window.find_by_id('new_user').input.disable! window.find_by_id('new_user_species').input.any? do |element| element.enabled? end.should be_false end end # visible? describe '#visible?' do it 'is true if all the elements are visible' do window.find_by_tag(:ul).visible?.should be_true end it 'is false if not all elements are visible' do @collection.visible?.should be_false end end # show! describe '#show!' do it 'shows all the elements' do @collection.show! window.find_by_id('hidden').visible?.should be_true end end # hide! describe '#hide!' do it 'hides all the elements' do @collection.hide! window.find_by_id('outer_container').visible?.should be_false end end end