I'm trying to upload a picture with watir and phantomjs but it's failed.
Html code is:
<div class="qq-uploader">
<div class="qq-upload-drop-area" style="display: none;">
<span>Drop files here to upload</span>
</div>
<div class="qq-upload-button" style="position: relative; overflow: hidden; direction: ltr;">
<div>Click or Drop for upload images</div>
<input multiple="multiple" type="file" name="qqfile">
</div>
<span class="qq-drop-processing">
<span>Processing dropped files...</span>
<span class="qq-drop-processing-spinner"></span>
</span>
<ul class="qq-upload-list"></ul>
</div>
</div>
i tried
require 'phantomjs'
require 'watir'
require 'watir-webdriver'
Selenium::WebDriver::PhantomJS.path = '/phantomjs/bin/phantomjs'
b = Watir::Browser.new(:phantomjs)
b.goto("http://website.com")
b.text_field(:name => /title/).set 'My title'
b.div(:id => "restricted-fine-uploader").fire_event :click
file = "/Users/Tom/Pictures/image.jpg"
b.file_field.set(file)
and
b.div(:id => "restricted-fine-uploader").fire_event :click
file = "/Users/Tom/Pictures/image.jpg"
b.file_field(:name => "qqfile").set(file)
But it doesn't work, i have a Net::ReadTimeout error. Where am I wrong? thx
Yes this is a known phantomjs bug: https://github.com/detro/ghostdriver/issues/183
Phantomjs driver has not been actively maintained for years. The Selenium team generally recommends against its use for testing.
Related
I was trying to test the file upload feature of the web platform using the cypress-file-upload package on jQuery.filer but unexpected behavior was met. Please see the attached code snippets for reference:
.html
<div>
<div class="form-group">
<h5 class="fs-subtitle">National card ID (NRIC) front </h5>
<input type="file" name="nric_front" id="filer_input"
class="form-control nric_front" required>
</div>
</div>
.js
$('#filer_input').filer({
showThumbs: true,
addMore: false,
allowDuplicates: false,
extensions: ['pdf', 'jpg', 'png', 'jpeg'],
fileMaxSize: 10,
limit: 1,
changeInput: true,
removeConfirmation: true,
captions: {
feedback: "Choose file to upload",
removeConfirmation: 'Are you sure you want to remove this file?',
errors: {
filesLimit: 'Only 1 file are allowed to be uploaded.',
filesType: 'Only .pdf, .jpg, .png, .jpeg files are allowed to be uploaded.',
fileSize: '${name} is too large! Please choose a file up to ${fileMaxSize}MB.',
filesSizeAll: 'Files that you choose are too large! Please upload files up to ${fileMaxSize}MB.',
fileName: 'File with the name is already selected.',
folderUpload: 'You are not allowed to upload folders.'
}
}
});
.spec.js
cy.get('.jFiler-input').attachFile('example.jpg');
Cypress version: 6.2.1
Operating system: Pop OS 20.04
Browser: Chrome Version 87.0.4280.141 (Official Build) (64-bit)
Current behavior:
Expected behavior:
Any help is appreciated, thanks!
Note
HTML renders like this
<div class="jFiler-input">
<div class="jFiler-input-caption">
<span>Choose file to upload</span>
</div>
<div class="jFiler-input-button">Choose Files</div>
</div>
Ref jQuery.filer plugin.
From the examples, the rendered HTML is
<div class="jFiler jFiler-theme-default">
<input type="file" name="files[]" id="demo-fileInput-7" multiple="multiple"
style="position: absolute; left: -9999px; top: -9999px; z-index: -9999;">
<div class="jFiler-input">
<div class="jFiler-input-caption">
<span>Choose files To Upload</span>
</div>
<div class="jFiler-input-button">Choose Files</div>
</div>
</div>
so you would need to target the input sibling of .jFiler-input
cy.get('.jFiler-input')
.sibling('input')
.attachFile('example.jpg');
or from the top
cy.get('div.jFiler input')
.attachFile('example.jpg');
I'm trying to perform automated testing using Watir gem. I need to test whether the checkbox works by setting and clearing it.
The HTML for the checkbox is:
<md-checkbox aria-label="Remove" aria-invalid="false" aria-checked="false" tabindex="0" class="ng-pristine ng-valid md-default-theme ng-touched" role="checkbox" ng-model="user.remove_photo" style="margin-top: 0px;">
<div class="md-container" md-ink-ripple="" md-ink-ripple-checkbox="">
<div class="md-icon"></div>
<div class="md-ripple-container"></div>
</div>
<div ng-transclude="" class="md-label">
<span class="ng-scope">Remove</span>
</div>
</md-checkbox>
My test script:
require 'watir'
require 'watir-webdriver/wait'
browser = Watir::Browser.new :firefox
browser.goto 'https://54.69.254.137/webui#/landing'
browser.driver.manage.window.maximize
browser.button(:class =>'sign-in md-button md-default-theme').click
browser.text_field(:id =>'input_001').set('abcadmin#example.com')
browser.text_field(:id =>'input_002').set('password')
browser.button(:class =>'md-primary md-raised md-button md-default-theme').click
browser.button(:class =>'md-icon-button md-primary main-menu-toggle md-button md-default-theme').when_present.click
browser.link(:text =>'Edit Profile').when_present.click
browser.checkbox(:class => 'ng-pristine ng-valid md-default-theme-ng-touched').set
browser.button(:class => 'md-primary md-raised md-button md-default-theme').click
Gives following error:
unable to locate element using checkbox(:class => 'ng-pristine ng-valid md-default-theme- ng-touched').
The problem with the checkbox is that it is not an HTML checkbox - ie <input type="checkbox">. Instead it is a md-checkbox, which I believe is from the Angular Material library. As a result, Watir's checkbox method will not see it.
You will need to treat the md-checkbox as a generic element and use the click method to set/clear it:
browser.element(class: 'ng-pristine ng-valid md-default-theme-ng-touched').click
The class attribute does not look unique. You might want to use one of the other attributes instead. For example:
browser.element(aria_label: 'Remove').click
I am relatively new to parsing and would like to get more practice. I want to parse the following URL: http://www.goodreads.com/quotes/tag/hard-work.
I want to grab all quotes tagged "hard-work". This is what the site code breaks down to:
<div class="content">
<div id="siteheader" class="uitext">
<div class="mainContentContainer ">
<div class="mainContent">
<div id="premiumAdTop">
<div class="mainContentFloat">
<div id="flashContainer"> </div>
<div id="connectPrompt" style="">
<img style="float: left; margin: -3px 5px 0px 0px" src="http://s.gr-assets.com/assets/quote/quote_tiny-566b7de5e1ac5becd0dd8b2856f59228.jpg" alt="quote">
<h1>Quotes About Hard Work</h1>
<div class="leftContainer">
<div class="mediumText">
<div class="quote mediumText ">
<div class="quoteDetails ">
<a class="leftAlignedImage" href="/author/show/3916262.Babe_Ruth">
<div class="quoteText">
“It's hard to beat a person who never gives up.”
<br>
―
Babe Ruth
</div>
Right now my code is:
require "rubygems"
require "open-uri"
require "nokogiri"
#page = Nokogiri::HTML(open("http://goodreads.com/quotes"))
#div = #page.xpath("html/body/div[1]")
But the results aren't giving me the output that I want.
I think I ought to call the methods each and collect but I just don't know how to get to the node that I want, which I believe is contained somewhere in here:
<div id="connectPrompt" style="">
<img style="float: left; margin: -3px 5px 0px 0px" src="http://s.gr-assets.com/assets/quote/quote_tiny-566b7de5e1ac5becd0dd8b2856f59228.jpg" alt="quote">
<h1>Quotes About Hard Work</h1>
<div class="leftContainer">
<div class="mediumText">
<div class="quote mediumText ">
<div class="quoteDetails ">
<a class="leftAlignedImage" href="/author/show/3916262.Babe_Ruth">
<div class="quoteText">
“It's hard to beat a person who never gives up.”
<br>
―
Babe Ruth
</div>
Can anyone point me in the right direction please? How far in do I have to go into the div class to get what I want?
You can use the XPath:
//div[#class = 'quoteText' and following-sibling::div[1][#class = 'quoteFooter' and .//a[#href and normalize-space() = 'hard-work']]]
to select all the div elements whose class is quoteText and which are followed by a div with class quoteFooter containing a link with hard-work.
I'd like to be able to click (to see available options/list of accounts, seem to be hidden to start with) and then set a dijit widget "select_list" to a certain value.
I can find the object using
##ie.element(:css, "#accountSwitcherSelect.dijitDownArrowButton").flash
#works
but cannot use click or set with it:
##ie.element(:css, "#accountSwitcherSelect.dijitDownArrowButton").click
#no errors, but doesn't do anything
##ie.element(:css, "#accountSwitcherSelect.dijitSelectLabel").set("Account2")
#NoMethodError: undefined method `set' for <Watir::HTMLElement:0x4d6af60>
##ie.element(:css, "#accountSwitcherSelect.dijitSelectLabel").send_keys("Account3")
#NoMethodError: undefined method `send_keys' for <Watir::HTMLElement:0x4d6af60>
In the past the site was implemented using plain html and had a select_list, so
##ie.select_list(:name, "link").set(/Account1/i)
worked just fine.
Here's the current html behind the site:
<table id="accountSwitcherSelect" class="dijit dijitReset dijitInline dijitLeft dijitDownArrowButton dijitSelectFixedWidth dijitValidationTextBoxFixedWidth dijitSelect dijitValidationTextBox" lang="en-US" cellspacing="0" cellpadding="0" aria-haspopup="true" role="listbox" data-dojo-attach-point="_buttonNode,tableNode,focusNode" style="-moz-user-select: none; width: 207px;" tabindex="0" widgetid="accountSwitcherSelect" aria-expanded="false" aria-invalid="false">
<tbody role="presentation">
<tr role="presentation">
<td class="dijitReset dijitStretch dijitButtonContents" role="presentation">
<div class="dijitReset dijitInputField dijitButtonText" role="presentation" data-dojo-attach-point="containerNode,_popupStateNode" popupactive="true">
<span class="dijitReset dijitInline dijitSelectLabel dijitValidationTextBoxLabel " role="option">Account1</span>
</div>
<div class="dijitReset dijitValidationContainer">
</td>
<td class="dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer" role="presentation" data-dojo-attach-point="titleNode">
<input class="dijitReset dijitInputField dijitArrowButtonInner" type="text" role="presentation" readonly="readonly" tabindex="-1" value="? ">
</td>
Assuming that the the "select list" is similar to those on the digit.form.Select documentation page, you need to:
Click the dropdown arrow (an input element)
Click the cell that has the text you want (a td element)
In your case, it would look like:
##ie.input(:class => 'dijitArrowButtonInner').click
##ie.td(:class => 'dijitMenuItemLabel', :text => /Account1/i).click
Here is a working example (though it relies on the dijit css files still being available online).
require 'watir-webdriver'
browser = Watir::Browser.new
browser.goto "data:text/html,#{DATA.read}"
browser.input(:class => 'dijitArrowButtonInner').click
browser.td(:class => 'dijitMenuItemLabel', :text => 'Arizona').click
sleep(10) # Just so that you can see the dropdown has changed
browser.close
__END__
<html>
<head>
<link rel="stylesheet" href="https://dojotoolkit.org/reference-guide/1.9/_static/js/dijit/themes/claro/claro.css">
<script>dojoConfig = {async: true, parseOnLoad: true}</script>
<script src="https://dojotoolkit.org/reference-guide/1.9/_static/js/dojo/dojo.js"></script>
<script>require(["dojo/parser", "dijit/form/Select"]);</script>
</head>
<body class="claro">
<div name="select3" value="AL" data-dojo-type="dijit/form/Select">
<span value="AL"><b>Alabama</b></span>
<span value="AZ"><i>Arizona</i></span>
</div>
</body>
</html>
Watir-Classic
The above solution works for watir-webdriver, but not watir-classic. Clicking the dropdown (actually a table) is not triggering sufficient events to open the dropdown. As a work around, it seems you can use send_keys to trigger the right events.
Assuming that browser is opened to a page with the above html, the following will work:
browser.table(:id => 'dijit_form_Select_0').send_keys :enter
browser.td(:class => 'dijitMenuItemLabel', :text => 'Arizona').click
Note that the table in this code is the selected option (when the dropdown is closed).
my autocomplete call is showing nothing right now, because the div that i am inserting the ul into has its style set to display:none. using firebug, i can see the results are returned in a proper unordered list tag and when i edit the html from the firebug console and remove the style="display:none;", i see the autocomplete results. i added css for the autocomplete tags that are generated but this is getting overwritten by prototype 1.6.1/scriptaculous 1.8.3. also, i'm using rails 1.2.2
here is the code from my view:
<script type="text/javascript">
new Ajax.Autocompleter("autocomplete", "autocomplete_choices", "/campaigns/title_list", {tokens: ',', paramName: 'title'});
</script>
<input type="text" id="autocomplete" name="autocomplete_parameter"/>
<div id="autocomplete_choices" class="autocomplete"></div>
and here my controller action and partial:
def title_list
camp_title = params[:title]
#titles = Campaign.find(:all, :conditions => ["title ilike ?", "%#{camp_title}%"], :select => :title).collect { |camp| camp.title }
render :partial => "title_list"
end
_title_list.rhtml
<ul>
<% #titles.each do |t| %>
<li> <%= t %> </li>
<% end %>
</ul>
here's what i seen in firebug:
<div style="display: none; position: absolute; left: 8px; top: 123px; width: 155px;" id="autocomplete_choices">
<ul>
<li class="selected"> DirecTV Defender (Best Deal Ever) </li>
<li class=""> Defender DirecTV </li><li class=""> DirecTV Defender - Collections </li>
<li class=""> Defender DirectTV (Gotham Direct) </li>
</ul>
</div>
any suggestions would be greatly appreciated.
-h
You need to go into the auto_complete helper (inside the vendor directory) and change the line items.uniq to items.uniq.join
The reason is a change in the to_s behavior of Arrays in Ruby 1.9. Worked fine for me like this.