CasperJS - Click button based on value stored in variable - javascript

Based on the input variable "feeling", I would like to click a button (good,bad or ok). How do i specify the input variable in casper.click?
var feeling = 'bad'; //User can choose good, bad or ok
.
.
logit_feeling(feeling); //fucntion call
.
.
// fucntion defnition
var logit_feeling = function (feeling){
casper.then(function (){
casper.click(x('//*[text()='feeling']'));
});
}

You have to properly quote and build the string that you would pass to the XPath helper:
x('//*[text()="'+feeling+'"]')
Oftentimes HTML is written with a lot of whitespace which is not shown when it is rendered. You would need to make this a little more robust:
x('//*[contains(text(),"'+feeling+'")]')

kbet,
As the Artjom said, you can concatenate its variable in the XPath string and get the property element text ().
In some cases, you can still pursue, as well as the axes text () as may search for **. **.
For example:
'//a[.,"sample"]'
As above, the text is accurate as at the string. You can even compare some of the text, using the CONTAINS:
'//a[contains(.,"sample")]'
Another option you may consider is using casper.click () with the CSS path element (if you can):
casper.click("my > css > path");
I hope you can help! ;)

Related

Rails/Rspec/Capybara: Interpreting quotes for javascript string for execute script

Given that I need to set an element's selected index with javascript in capybara by the input name...
var element = document.querySelector("select[name='user[user_locations_attributes][0][location_attributes][state]']").selectedIndex = '50';
What is the proper way to interpret this as a string so it can be executed in Capybara with execute_script(function_name_string)? Because I keep getting syntax errors, unsure how to nest the " and ' quotations.
Easiest solution to your question is to use a heredoc
page.execute_script <<~JS
var element = document.querySelector("select[name='user[user_locations_attributes][0][location_attributes][state]']").selectedIndex = '50';
JS
Although if you have need for the element for anything else it's probably nicer to find the element in ruby and then just call execute_script on the element
el = find("select[name='user[user_locations_attributes][0][location_attributes][state]']")
el.execute_script('this.selectedIndex = 50;')
As a related question - is there a reason you're doing this via JS rather than just clicking on the correct option? If you're just scraping a page there's no issue, but if you're actually testing something this basically makes your test invalid since you could potentially be doing things a user couldn't
Since you commented that you are testing, you really shouldn't be doing this via JS, but should instead be using select or select_option. select takes the options string (which you should have - otherwise why have a select element in the first place)
select('the text of option', from: 'user[user_locations_attributes][0][location_attributes][state]')
select_option is called on the option element directly, which can be found in a number of ways, such as
find("select[name='user[user_locations_attributes][0][location_attributes][state]'] option:nth-child(50)").select_option

Converting href perl variables to normal scalar variables

I have these two variables that I am trying to compare. They both have the same value, however, one is a href variable - meaning, it's being read from a file like this
<a href=http://google.com>Variable</a>
It's read like this, but displayed as an anchor tag in the browser, so when I go to compare a value using print "$collect_zids{$key} --> $temp";I see in the browser as
Variable --> Variable
How it appears in the browser. One text another link.
I'm assuming these two values are different hence why this code does not run
if($collect_zids{$key} eq $from_picture){
print "<h1>Hello</h1>";
}
Is there a way I can convert the href variable into a normal scalar variable so that I can compare them?
Thanks!
P.S. I think Javascript might be the only way, however, I don't have any experience with it.
There is no such thing as an "href variable". You have two scalar variables. One contains plain text and the other contains HTML. Your task is to extract the text inside the HTML <a> tag from the HTML variable and to compare that text with the text from the plain text variable.
One way to do that would be to remove the HTML from the HTML variable.
my $html = '<a href=http://google.com>Variable</a>';
my $text = 'Variable';
$html =~ s/<.+?>//g;
if ($html eq $text) {
say "Equal";
} else {
say "Not Equal [$html/$text]";
}
But it cannot be emphasised enough that parsing HTML using a regular expression is very fragile and is guaranteed not to work in many cases. Far better to use a real HTML parser. HTML::Strip is made for this very purpose.
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use HTML::Strip;
my $html = '<a href=http://google.com>Variable</a>';
my $text = 'Variable';
my $parser = HTML::Strip->new;
$html = $parser->parse($html);
if ($html eq $text) {
say "Equal";
} else {
say "Not Equal [$html/$text]";
}
It's also worth pointing out that this is answered in the Perl FAQ
How do I remove HTML from a string?
Use HTML::Strip, or HTML::FormatText which not only removes HTML but
also attempts to do a little simple formatting of the resulting plain
text.
Update: In a comment, you say
I have no way of using these methods since I am not explicitly defining the variable.
Which is clearly not true. How a variable is initialised has no bearing whatsoever on how you can use it.
I assume your HTML text is in the variable $from_picture, so you would strip the HTML with code like this:
my $parser = HTML::Strip->new;
my $stripped = $parser->parse($from_picture);
if($collect_zids{$key} eq $stripped){
print "<h1>Hello</h1>";
}
I have no idea where you got the idea that you couldn't use my solution because I was directly initialising the variables, where you were reading the data from a file. An important skill in programming is the ability to see through complex situations and extract the relevant details. It appears you need to do some more work in this area :-)
I found the answer using the Perl module HTML::FormatText;
use HTML::FormatText;
my $formatter = HTML::FormatText->new();
my $string = HTML::FormatText->format_file("path_to_the_file"); #$string variable to hold the result and the path must be for a file.
After using the HTML::FormatText module, I was able to get the raw string that was being read, instead of it being interpreted as HTML. So, I was getting <a href=http://google.com>Variable</a> returned, instead of just Variable. After getting the raw string, I could use regex to extract the parts that I needed.
Credit to - https://metacpan.org/pod/HTML::FormatText

Hide part of the text returned from the server

On my webpage I want to hide part of the text in an object returned by the server.for example:
<div>
<h4>{{name.SubName}}</h4>
</div>
The string returned by {{name.SubName}} contains a name followed by some text within brackets, like this "Sample Name(XYZ)". I want to be able to hide anything that is appearing within brackets i.e. (XYZ) in this case.
Any suggestions on how I can make this work?
upon returning from server, add a function to the object that returns intended format, like
$.get('example', function(name){
name.cleanSubName = function(){
this.SubName.replace(/\([^)]+\)/, "")
}
});
and use it in the template like,
<h4>{{name.cleanSubName()}}</h4>
regex borrowed from #Rohan Kumar :)
hope this helps.
Better way is to don't respond the name having () from server and if there are () then you can replace it at server side(if the full name is not in use at client side).
In PHP you can use the preg_replace() like,
echo preg_replace("/\([^)]+\)/","","Sample Name(XYZ)"); // 'Sample Name'
And in Javascript you can use,
"Sample Name(XYZ)".replace(/\([^)]+\)/,""); // you need to use name instead of string

Javascript regex to replace ampersand in all links href on a page

I've been going through and trying to find an answer to this question that fits my need but either I'm too noob to make other use cases work, or their not specific enough for my case.
Basically I want to use javascript/jQuery to replace any and all ampersands (&) on a web page that may occur in a links href with just the word "and". I've tried a couple different versions of this with no luck
var link = $("a").attr('href');
link.replace(/&/g, "and");
Thank you
Your current code replaces the text of the element within the jQuery object, but does not update the element(s) in the DOM.
You can instead achieve what you need by providing a function to attr() which will be executed against all elements in the matched set. Try this:
$("a").attr('href', function(i, value) {
return value.replace(/&/g, "and");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
link
link
Sometimes when replacing &, I've found that even though I replaced &, I still have amp;. There is a fix to this:
var newUrl = "#Model.UrlToRedirect".replace(/&/gi, '%').replace(/%amp;/gi, '&');
With this solution you replace & twice and it will work. In my particular problem in an MVC app, window.location.href = #Model.UrlToRedirect, the url was already partially encoded and had a query string. I tried encoding/decoding, using Uri as the C# class, escape(), everything before coming up with this solution. The problem with using my above logic is other things could blow up the query string later. One solution is to put a hidden field or input on the form like this:
<input type="hidden" value="#Model.UrlToRedirect" id="url-redirect" />
then in your javascript:
window.location.href = document.getElementById("url-redirect").value;
in this way, javascript won't take the c# string and change it.

Combining jQuery .val() and .contains()

I'm fairly new to jQuery and I ran into this problem while trying to combine .val() with :contains(). I'm trying to get input from a text field and check to see if that input is in a paragraph, and highlight it in that paragraph. All of the code here is strictly based on information I got from the jQuery API, but I can't get it to work.
See the jsfiddle here: http://jsfiddle.net/tUKp8/
Here is my jQuery code:
$("input").keyup(function () {
var value = $(this).val();
$("p:contains('value')").css("text-decoration", "underline");
}).keyup();
you neeed
$("p:contains(" + value +" )").css("text-decoration", "underline");
Two problems:
The string is not being concatenated--variable names need to be outside of strings and added using the concatenation operator (+). Right now you are passing in the string 'value' to contains(), which will only find p elements that contain the text 'value'. Instead, concatenate using the variable you declare, like so:
$("p:contains(" + value + ")").css("text-decoration", "underline");
Now value will be passed into the jQuery selector.
You don't need to chain keyup() to the end. Passing no arguments into this method triggers a keyup event, which, at least in this limited example, doesn't do anything. See the jQuery API for keyup() here: http://api.jquery.com/keyup/. What you're doing with the last .keyup() falls into the third category.
Hope this helps!

Categories