How to Detect Partial Text within a Selector using CasperJS - javascript

I am using CasperJS for functional testing, and I want to check if an error message is displaying in a page.
I am using:
test.assertSelectorHasText('#iccid-error', 'CC-ICCID-01');
That works fine but only if I use the whole text (not part of it).

According to the documentation, the CasperJS function assertSelectorHasText():
Asserts that given text exists in elements matching the provided selector expression.
In other words, this function will work for full and partial strings, and the test will pass if the string exists within the element.
I ran a simple test to verify the accuracy of the function.
Command Line:
casperjs casperjs.js
Result:
# How to Detect Partial Text within a Selector using CasperJS
PASS Find "CC" within the selector "#iccid-error"
PASS Find "CC-ICCID" within the selector "#iccid-error"
PASS Find "CC-ICCID-01" within the selector "#iccid-error"
PASS How to Detect Partial Text within a Selector using CasperJS (3 tests)
casperjs.js:
phantom.casperTest = true;
var casper = require('casper').create();
casper.test.begin('How to Detect Partial Text within a Selector using CasperJS', 3, function (test) {
casper.start('https://example.com/test.php', function () {
test.assertSelectorHasText('#iccid-error', 'CC');
test.assertSelectorHasText('#iccid-error', 'CC-ICCID');
test.assertSelectorHasText('#iccid-error', 'CC-ICCID-01');
}).run(function () {
test.done();
});
});
casper.on('run.complete', function () {
this.exit();
});
example.com/test.php:
<!DOCTYPE html>
<html>
<body>
<div id="iccid-error">CC-ICCID-01</div>
</body>
</html>
As a result, I can conclude that the function assertSelectorHasText() does in fact search for partial strings in the element matching the selector given.

Related

How to get property js content edit it and run with puppeteer

im trying to use puppeteer to get property content of an element, edit it and run the edited version.
For example:
There is this element:
What I need is to get the onclick content, remove the _blank parameter and run the rest of the function... Any ideas?
maybe not the most powerful solution out there but if you only need to do this on this specific tag you could set onclick's attribute with JavaScript within page.evalauate like this:
await page.evalauate(() => {
document
.querySelector(".btn.btn-info")
.setAttribute(
"onclick",
document
.querySelector(".btn.btn-info")
.onclick.toString()
.split("\n")[1]
.replace(",'_blank'", "")
);
});
await page.click(".btn.btn-info");
what's going on here?
we run plain JavaScript within the page's scope with page.evaluate
we select the tag with document.querySelector
and set its onclick attribute (not its property!)
getting the node value of onclick as string:
mojarra.jsfcljs(document.getElementById('j_idt58'),{'j_idt58:j_idt201:0:j_idt203':'j_idt58:j_idt201:0:j_idt203'},'_blank');return false
using the 2nd line of the function (as we don't need the 1st 'function onclick(event) {' line when we reassign it as the attribute)
and replacing ,'_blank' parameter from the original function (string).
the result will be:
mojarra.jsfcljs(document.getElementById('j_idt58'),{'j_idt58:j_idt201:0:j_idt203':'j_idt58:j_idt201:0:j_idt203'});return false
finally clicking the button with page.click executes the new function
alternatively, you can use attributes.onclick.nodeValue if you are not comfortable with toString().split("\n")[1] above:
document.querySelector(".btn.btn-info").attributes.onclick.nodeValue.replace(",'_blank'", "")

WebdriverIO - How can I retrieve the HTML of the currently focused/selected/active element?

I am looking to retrieve a focused element's HTML. Looking at the webdriver.io documentation, the method .getActiveElement() is supposed to do the trick. However, my IDE (WebStorm) shows an error stating that it is an "unresolved function or method" (the method isn't recognized). I've also seen someone mention the method .elementActive(), however this method shows up unrecognized as well.
Help! How can I retrieve the HTML of the current focused element?
If you're using WebdriverIO v5, you should be able to run the following:
const activeElement = $(function () { return document.activeElement });
const html = activeElement.getHTML();
console.log(html);
https://webdriver.io/docs/selectors.html#js-function

Testing multiple HTML pages with CasperJS?

I'm working with CasperJS on a webpage that has a search box. Using Casper, I'm successfully able to perform a search and see that the form is filled and execute the search, however I'm having trouble specifically getting the number of results to test that it's valid.
When I look at the source of the webpage, I have the XPath of the element and it's nested in a few divs.
But when I try to either do assertExists() on that path, or even return the result of getElementByXPath() to a var, it doesn't work. In the first case the test fails and in the second case it prints null.
This is the XPath:
//*[#id="total"]
Here is what the snippet of source looks like:
<div id="pgContent"><div id="results_pagination1_container">
<span style="float: right; font-size: .9em">
Found <span id="total">721</span> item(s)</span>
</div>
This is the CasperJS code, relevant to here.
casper.test.begin(
'Testing that we get the right amount of results for a search query',
2, function suite(test) {
casper.start(catapult, function() {
test.assertTitle("Search", "Search"); // Good
test.assertExists('#input-searchbox'); // Good
this.fillSelectors('form#inputForm', {
'input[name="queryStr"]' : 'airplane'
}, true);
//this.click('input#btnSearch');
});
casper.then(function() {
var resultsNum = __utils__.getElementByXPath('//*[#id="total"]');
this.echo(resultsNum);
test.assertExists('//*[#id="total"]');
});
Clientutils and DOM access only in page context
The CasperJS clientutils module is only defined in the page context. Whenever CasperJS starts, it injects those utils into the page for later convenience. The problem is that the page and its DOM are only accessible from inside of the evaluate() function.
Another thing to remember is that you cannot get DOM nodes out of the page context. Either you do your stuff completely in the page context (inside of evaluate()) or you get a representation of the node like the textContent property:
var resultsNum = this.evaluate(function(){
return __utils__.getElementByXPath('//*[#id="total"]').textContent;
});
Here is the bit from the documentation (since CasperJS is built on top of PhantomJS):
Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Closures, functions, DOM nodes, etc. will not work!
Difference between CSS selectors and XPath expressions
The other thing is that if not otherwise noted through the name all functions assume that the selectors are CSS selectors. Looking at test.assertExists('//*[#id="total"]'); makes it clear that '//*[#id="total"]' is not a CSS selector, but an XPath expression. You can use XPath expressions in CasperJS through the XPath utility:
var x = require('casper').selectXPath;
test.assertExists(x('//*[#id="total"]'));
or you can simply use the equivalent CSS selector:
test.assertExists('#total');

Get ajax value from JavaScript function

I'm not an JS developer, so forgive me if this is a stupid question.
I have this web application, that uses ajax to keep the data update on the screen, but I'm not able to use the ajax value in my JS function, the code generated by my application is:
<span id="c0"></span>
In the web page I just see the numeric value, e.g. 5 and it's updated every second as expected, so I tried to use the same in my JS function:
<script type="text/javascript">
function getPoint()
{
console.log ('<span id="c0"></span>');
return 0;
}
</script>
But in the Chrome's log I just see <span id="c0"></span> instead of a numeric value.
Try the following:
<script type="text/javascript">
function getPoint()
{
var span_element = document.getElementById("c0");
var content = span_element.innerHTML;
console.log(content);
return content;
}
</script>
Explanation:
First you need to access the DOM element of javascript. You identified the element with the id: "c0". To access the element you need to use the function: document.getElementById("someID");
With the element you can do a lot of things. In this case you want to access whatever is inside the tag , so what you want is its inner HTML.
If you are using JQuery, you can also get its content like this:
var span_element = $("#c0");
var content = span_element.text();
Console.log simply logs whatever string you send it as a parameter. So what you are seeing is the expected behavior.
Assuming you are using jQuery, and the ajax returned value is being displayed in the span (id = "c0"), this console.log statement should work:
console.log($("#c0").text());
$("#c0") returns the jQuery object using the id selector (#).

Javascript retrieve absolute XPATH via ID of Node

Hello am trying to retrieve the XPATH of a document via the ID of the node, I saw this to be a simple matter when looking at the code a simple:
//iframe[#id=key];
But it won't work, I've tried every combination of syntax I can think of and not luck, the print out is "undefined". This is my code
function getNode(htmlURL, filename, xpath, callback){
var key = filename+xpath;
var frame = document.getElementById(key);
frame.addEventListener("load", function(evt){
var value= frame.contentDocument.evaluate(xpath, frame.contentDocument, null,9,null);
if(value!=null){
callback(value);
}
}, false);
frame.contentWindow.location.href = htmlURL;
}
function init(htmlURL, filename, xpath){
getNode(htmlURL, filename, xpath, function(node) { console.debug(node.outerHTML); });
}
Am trying to get the xpath inside the iframe, so I thought I'd have to point it to the xpath to the iframe first
If you want to find an element inside of an iframe then you need to use the evaluate method on the document in the iframe e.g.
frame.contentDocument.evaluate(xpath, frame.contentDocument, null,9,null)
But if you set the src to load an HTML document don't expect to be able to access nodes in the document in your code setting the src, instead set up an onload event handler to wait until the document has been loaded. In the event handler you can then access the nodes in the loaded document.
You are getting undefined because your xpath syntax translates to a code comment in JavaScript.
What you probably want is:
var finalxpath = "//iframe[#id=key]";
Note the quote characters which makes your xpath a string literal value.

Categories