Unable to locate element by xpath - xpath

Here is source html:
<div id="alert_signin" class="alert_modal_error">
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
Invalid username or password.
</div>
</div>
What I really need is to check if message "Invalid username or password." appears (python + selenium webdriver ). But I was unlucky to find it using xpath like
find_element_by_xpath('//div[#id=\'alert_signin\']/div[#class=\'alert\']').text
So I've decided to find exact xpath using message text. I've tried several options like
find_element_by_xpath('//*[text()[contains(.,\'Invalid\')]]')
or
find_element_by_xpath('//*[contains(., \'Invalid username or password.\')]')
but each time got "NoSuchElementException: Unable to locate element: {"method":"xpath","selector": blablabla"
Please advice

You cannot directly point your expressions to the text nodes in Selenium.
Instead, I would get the entire "alert" text:
alert_text = driver.find_element_by_css_selector("#alert_signin .alert").text
Then, you can either apply the "contains" check:
assert "Invalid username or password." in alert_text
Or, remove the "x" part:
alert_text = alert_text.replace(u"×", "").strip()
assert alert_text == "Invalid username or password."
Examples in Python.

Can you provide some more info, please:
-- Is there a button that you click to get the message?
-- Is the message within a browser-specific alert, or is it a displayed text on the page?
(if the latter is the case, try something like if "Invalid username or password." in driver.page_source: print "SUCCESS!")

actually what I've found is that the only thing I need is using implicitly_wait.
this code works fine:
sign_in.click()
driver.implicitly_wait(30)
alert_text = driver.find_element_by_css_selector("div#alert_signin > div.alert.alert-danger.alert-dismissable").text
alert_text = alert_text.replace(u"×", "").strip()
assert alert_text == "Invalid username or password."
however note from alecxe was very useful while I was trying to verify my approach
You cannot directly point your expressions to the text nodes in Selenium.

Related

reCaptcha V2 is working but not preveting SPAM

The front end of reCaptcha seems to work fine. It will time out and will even challenge you. The reCaptcha Admin panel says it is working and the chart shows a bunch of fails, BUT spam keeps coming through. I am assuming it must be the validation that fails. But why? What is wrong with this code that spam keeps on getting through?
if(isset($_POST['submit'])){
if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])){
$verify_captcha = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret_key.'&response='.$_POST['g-recaptcha-response']);
$verify_response = json_decode($verify_captcha);
if($verify_response->success){
$returnMsg = 'Your email has been submitted successfully.';
include ('./includes/sendmail.php');
include ('./forms/sectionhead.tpl');
echo "<p class='returnmsg'>reCAPTCHA was completed successfully!<br> $returnMsg</p>";
//echo $returnMsg;
echo "
<div class=\"bg-theme-colored\" style=\";color:#754c00;border:1px solid #11477f;text-align:center;padding:25px;\">
<h4><span>Success!</span> Your message has been sent.</h4>
<h5>A copy of your message has been emailed to $_POST[form_email]</h5>
<h5>Thank you for your interest in the North American Bison </h5>
</div>";
include ('./forms/contactend.php');
exit();
}else{
$returnMsg = 'reCaptch verification failed, please verify again.';
include ('./forms/sectionhead.tpl');
echo '<p class="returnmsg">reCAPTCHA error: ' . $returnMsg . '</p>';
include ('./forms/contactform.php');
include ('./forms/contactend.php');
exit();
}
}else{
$returnMsg = 'Please check the CAPTCHA box.';
include ('./forms/sectionhead.tpl');
echo '<p class="returnmsg">reCAPTCHA error: ' . $returnMsg . '</p>';
include ('./forms/contactform.php');
include ('./forms/contactend.php');
exit();
}
}
Since you may ask something like are you sure it is SPAM, here is an example or 2:
Name: ApkJoysuevy
Email: allisonharry683#gmail.com
City: Moscow
State: AL
Message: You can download any of the provided casinos above without any problems. If you download the casino app, it will position like a regular mirror image of the power supply place from the mobile version. Unfortunately, all the apps you download choose however do one's daily dozen on Android. Download casino in 1 click from the tabulate, these are the most advanced transportable applications. The best casino apps for Android The problem is that declaration Android apps and downloading them can be iffy, as Google doesn't authorize legitimate folding money Android casinos to be placed in the Flirt Store. Download casino app But don't worry .... etc
Name: PirikusMeste
Email: prikus#draviero.xyz
City: Ekaterinburg
State: BC
Message: Ñ‚Ñ€Ð¾Ð¸Ñ†ÐºÐ°Ñ Ð¿Ñ€Ñжа интернет
Any thoughts appreciated cause I am at a loss

Geb Test DOM Element Exists And Then Is Removed On Next Page Load

I'm pretty new to Geb, but I'm facing an odd issue that the docs don't seem to address. I have a pretty simple scenario to test: log in as admin, open applications, verify that an 'apply' button appears on the home page. Then close applications and verify that the button is gone from the home page. I can perform this test manually with success and there is nothing on the server side (cache wise) preventing this from succeeding but when I run the test via Gradle it fails because the button is still being shown on the home page after the 'close' test. Note that the test also verifies that the config was saved with the proper value.
Here's my test code:
def "can open applications"(){
when:
to ManageConfigPage
and:
configFormModule.toggleApplications(true)
then:
at ManageConfigPage
assert $('#messages').text() == "Config successfully updated"
assert $('td', text: 'config.application_closed').closest('tr').find('input').value() == "0"
then:
to HomePage
assert applyButton
}
def "can close applications"(){
when:
to ManageConfigPage
and:
configFormModule.toggleApplications(false)
then:
at ManageConfigPage
assert $('#messages').text() == "Config successfully updated"
assert $('td', text: 'config.application_closed').closest('tr').find('input').value() == "1"
then:
to HomePage
assert !applyButton
}
Here's the applyButton content definition:
applyButton(cache: false, required: false){ $('#apply_button') }
I also tried using the selector directly in the test instead of inside a content definition and that did not work either.
So what's going on here? Is the home page being cached in it's entirety? If so, how do I prevent or refresh it? This seems like Geb 101 but the manual doesn't really address this issue.
Edit: adding the test result for completeness:
Condition not satisfied:
!applyButton
||
|applyButton - SimplePageContent (owner: HomePage, args: [], value: null)
false
at AdminSpec.can close applications(AdminSpec.groovy:59)
Is the button element not included in the html or is is simply hidden? If it's hidden then you will need to check that it's not displayed:
!applyButton.displayed

how to test / interact with AJAX autocomplete and Capybara / Poltergeist

I am trying to interact with an external website at: http://is.gd/LtgYEk
I need to be able to fill in the input with id="textOrigen" here is the html
<p>
<label class="form-label">Departing from:</label>
<span class="label-field">
<input type="text" autocomplete="off" onblur="onblur2('textOrigen');" onfocus="initID('textOrigen');" size="17" id="textOrigen" name="text" maxlength="40" style="position:static;color: #505050;">
<select style="display:none" onchange="clearValidate(); Origen();" class="validate[dynamic]" id="cmbOrigen" name="cmbOrigen">
<option value="-1" selected="selected">Origin</option>
</select>
<label class="label-error" id="lblerrorOrigen"></label>
</span>
</p>
I put together a simple ruby script using 'capybara/poltergeist'
I am unable to replicate the browser behavior, which is:
on click the input field default value is highlighted thus being deleted as you start typing.
I lost track of all different variations I tried, but tried many. I found another SO post which seemed somewhat useful but it didn't help
This is the last revision of the method to fill this field:
def session.fill_autocomplete(field, options = {})
execute_script %Q{ $('##{field}').trigger('focus') }
fill_in field, with: options[:with]
execute_script %Q{ $('##{field}').trigger('focus') }
execute_script %Q{ $('##{field}').trigger('keydown') }
selector = %Q{#output div:contains('#{options[:with]}')}
execute_script "$(\"#{selector}\").mouseenter().click()"
end
As I wrote the script is very simple, the only other relevant bit is when the session is instantiated with:
session = Capybara::Session.new(:poltergeist)
Any help would be greatly appreciated.
I noticed that using the right version of phantomjs is fundamental.
Although 2.x is out, I noticed that phantomjs 1.8.2 behaves much more as expected and is way less buggy.
I'm currently testing autocompleted fields in RailsAdmin with success without using any delay technique.
def fill_in_autocomplete(selector, text)
find(selector).native.send_keys(*text.chars)
end
def choose_autocomplete_entry(text)
find('ul.ui-autocomplete').should have_content(text)
page.execute_script("$('.ui-menu-item:contains(\"#{text}\")').find('a').trigger('mouseenter').click()")
end
An example selector for fill_in_autocomplete would be:
".author_field .ui-autocomplete-input"
I found the solution after testing in many ways.
The key was to add some delay to allow the auto suggest div to be populated.
Here is the method that worked:
def session.fill_city(field, options = {})
sleep 3
script = %Q{ $("#{field}").focus().keypress().val("#{options[:with]}") }
execute_script(script)
sleep 2
find('#output').find('div').trigger('click')
end

How can I click the tricky logout link and logout by using VBScript

Guys,
I met the webpage where the logout function was coded like this:
<div class="l login_even">
<span class="logout">
"("
<a class="logoutBtn" href="javascript:void(0);">logout</a>
")"
</span>
</div>
I can use the iteration of tagName "a" to locate the tag. However, I wanted to click the logout button and logout the webpage. I got error if I wrote down the code snippetsas follows:
script snippet:
If IEApp.Document.readyState="complete" Or IEApp.Document.readyState="loaded" Or IEApp.Document.readyState="interactive" Then
Set objDoc = IEApp.Document
Set allTags = objDoc.getElementsByTagName("a")
For Each aTag In allTags
If aTag.innerHTML = "logout" Then
WSH.Echo("Found!")
aTag.click()
objDoc.Location.Reload(True)
'Else
'WSH.Echo("Not Found!")
End If
Next
End If
error message:
Line:28
Char:3
Error:Permission denied: 'innerHTML'
Code:800A0046
Source:Microsoft VBScript runtime error
Could any guy help me? Thanks.
Use If aTag.innerText = "logout" Then instead of innerHTML

How can I measure the length of a long string in Ruby? SciTE and command prompt aren't working.

I've written a program that measures my typing speed. As part of this, I need it to count how many characters I've typed. I did that with
text = gets.chomp
puts text.length.to_s
Unfortunately, I can't get this working for a long string.
In the SciTE editor, .length doesn't work properly, so instead of giving me the length of the string, it gives me the character count of everything I've typed, including corrected mistakes - if I typo "Hrello" and correct it to "Hello", it'll still return 6 instead of 5.
I googled this, and the suggested fix was to run the program from the command prompt instead. In the command prompt, .length works fine, but it turned out that I can't type in more than 264 characters.
So I tried to put a GUI on the program with Shoes:
Shoes.app :width => 300, :height => 300 do
button "Start." do
text = ask "Type here."
para text.length.to_s
end
end
and discovered that Shoes' input box has an even shorter character limit.
I'm running Windows 7, Ruby 1.9.2, SciTe version 2.29 and Shoes Policeman Revision 1514.
How can I run this program so it'll correctly measure the length of a really long string? I'd be happy with any solution that fixes the command prompt or Shoes character limit, the SciTE bug, or just a suggestion for a different way to execute ruby programs where this will work.
I'd be happy with [...] a suggestion for a different way to execute ruby programs where this will work.
What about a simple web app? Here is a simple Sinatra app that accomplishes exactly what you have asked with a very large character limit.
require 'sinatra'
get '/' do
%{<html>
<body>
<form method="post">
<textarea name="typed"></textarea>
<input type="submit">
</form>
</body>
</html>
}
end
post '/' do
"You typed #{params['typed'].length} characters."
end
To run the app you can use something as simple as ruby sinatra_example.rb to use a built-in web server. Or, you can deploy this app using any of several web servers.
If you need timers this should be easy to accomplish through javascript and include in the form submit.
Ok, your question is not accurately titled, but lets see:
There is a very broad number of options of using command prompt, and you should consider running a simple script in ruby on it.
On command line from windows, try typing ruby C:/path_to_folder_program/program.rb
If it won`t execute, you can find on ruby folder some executable called ruby and should, from command prompt on that path, run it like above.
But let me ask you, why ruby? Other more accessible and user-friendly programming languages, like javascript would behave better and would be easier to make your program accessible.
- EDIT -
Seems shoes can handle more chars, use edit_box instead of ask:
In Shoes:
Shoes.app do
#txt = edit_box
button("How many"){ alert(#txt.text.size) }
end
Anyway, before trying shoes I did the exercise with that I knew, here it is:
In javascript:
<script>
function start_stop(){
var txt = document.getElementById('txt');
var btn = document.getElementById('btn');
if( txt.disabled ){
txt.value = '';
txt.disabled = false;
btn.value = 'Stop';
txt.focus();
startTime = new Date().getSeconds();
} else {
txt.disabled = true;
btn.value = 'Start again';
timeNow = new Date().getSeconds();
alert(txt.value.length + " characters in " + (timeNow - startTime) + " seconds.");
}
}
</script>
<input type='button' id='btn' onclick='start_stop()' value='Start'>
<textarea id='txt' rows='8' cols='80' disabled></textarea>
In Ruby using Qt: (replicating the same idea as in the javascript one)
require 'Qt'
class MyWidget < Qt::Widget
slots :start_stop
def initialize
super
setFixedSize(400, 120)
#btn = Qt::PushButton.new("Start")
#txt = Qt::TextEdit.new ; #txt.readOnly = true
vbox = Qt::VBoxLayout.new
vbox.addWidget #btn
vbox.addWidget #txt
setLayout vbox
connect(#btn, SIGNAL("clicked()"), self, SLOT(:start_stop))
end
def start_stop
if #txt.readOnly
#txt.plainText = ''
#txt.readOnly = false
#btn.text = "Stop"
#txt.setFocus
#startTime = Time.now
else
#txt.readOnly = true
#btn.text = "Start again (#{#txt.plainText.size} chars #{(Time.now - #startTime).to_i} in seconds)"
end
end
end
app = Qt::Application.new(ARGV)
widget = MyWidget.new
widget.show
app.exec

Resources