How to resolve NoSuchElement exception in selenium? - javascript

I had one link initially. Now I received the requirement of showing button instead of a link for A/B testing. I have to make their ids same since I don't want to write a new test for the button.
To decide which to display I added two unique classes in the li item. This is working fine.
But on testing it starts failing, giving the message "Subscriber link is not available" although button is present there.
I thought that it might failing because of two same ids are there so i added two same classes and change the selector from id to class. But it still failing.
<li class="not_subscriber subscriber-text-link " style="display:none">
<a class="link-orange subscribe" href="" id="subscribe_link"> Subscribe </a>
</li>
<li class="not_subscriber subscriber-orange-btn " style="display:none">
<a class="btn-orange subscribe" href="" id="subscribe_link" > Subscribe </a>
</li>
#FindBy(css = ".subscribe")
#NoSuchElementDescription("Subscriber link is not available")
protected WebElement _subscribeLink;
Is there any way such that i dont have to write new test and change ids and test will start passing??

Can you please try below Xpath:-
//li[#class='not_subscriber subscriber-orange-btn ']/a[#class='btn-orange subscribe']
Hope it will help you :)

Change the selector to xpath. Almost every element has an xpath. And be sure to replace the double quotes to single quotes. It should be more reliable than class or id selectors.

Related

How to .click() on a JavaScript object?

I'm currently working with selenium chromedriver in python and I want to collapse this open.
<a id="pp-T0-81" href="javascript:void(0)" data-action="a-expander-toggle" class="a-expander-header a-declarative a-expander-inline-header pmts-apply-claim-code a-spacing-base a-link-expander" data-a-expander-toggle="{"allowLinkDefault":true, "expand_prompt":"", "collapse_prompt":""}"><i class="a-icon a-icon-collapse"></i><span class="a-expander-prompt"><span class="a-size-base xh-highlight">Voer een cadeaubon- of promotiecode in.</span></span></a>
However the id="pp-T0-81" seems to change when the page is refreshed.
Not very experienced but I tried to use Xpath but that didn't seem to work.
It's hard to know what XPath makes sense in your scenario, but if you think data-action and class are unique and will stay stable (you say that id kept changing), then you could use those two:
const paragraphCount = document.evaluate( `//a[#data-action='a-expander-toggle'][#class='a-expander-header a-declarative a-expander-inline-header pmts-apply-claim-code a-spacing-base a-link-expander']`, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue
console.log(paragraphCount)
<a id="pp-T0-81" href="javascript:void(0)" data-action="a-expander-toggle" class="a-expander-header a-declarative a-expander-inline-header pmts-apply-claim-code a-spacing-base a-link-expander" data-a-expander-toggle="{"allowLinkDefault":true, "expand_prompt":"", "collapse_prompt":""}"><i class="a-icon a-icon-collapse"></i><span class="a-expander-prompt"><span class="a-size-base xh-highlight">Voer een cadeaubon- of promotiecode in.</span></span></a>
Using dynamic id's for testing isn't really a reliable idea. I'd suggest using DOM nesting to target the element.

AngularJS: Creating a class that I can use in my app.js file to use hyperlink pictures

In my app.js file I have classes that are data driven, such as text and picture classes. I have a hyperlink class for which I used Href that looks like this:
div class = "links" ng-if="field.fieldLink">
<a ng-if="content.LinkField.fieldLinkNewTab !== false" target="_blank"
ng-href="{{ content.fieldLink.fieldLinkHref }}">{{
content.fieldLink.fieldLinkText }}</a>
<a ng-if="content.fieldLink.fieldLinkNewTab === false" ng-href="{{
content.fieldLink.fieldLinkHref }}">{{
content.fieldLink.fieldLinkText }} </a>
</div>
So this way I can easily use it like this in my .JS file:
fieldLink
{
fieldLinkHref: "www.etc.com",
fieldLinkText: "click here for random website",
The problem that I am having is making a field for an image:
fieldLinkImage: "documents/pictures/etc.jpg"
fieldLinkHref: "www.etc.com",
Clicking the picture should redirect me to the url.
I can do this in my .html file just fine, by simply wrapping the image in the class, but I want to select the image in my .JS file.
How do I make this happen without hard coding the links and images in the .html file ?
Thank you!
Sorry about this but I will criticize your code a bit.
First to point out that you have a typo, LinkField should probably be fieldLink in your first <a> element.
Next, why are you comparing !== false when you can just check if var is true or truthy (just put variable in condition - no need to compare with anything - if it's there or is true it will be truthy).
Also to create a new element just because you need to have different attribute is bad, you will get tons of code and get lost at some point. Instead use ng-attr-target which will give you same thing in one line - puts target (or any other) attribute based on condition.
But all of that can be fixed of course, I will take a wild guesses on your data structure during this since you haven't provided jsfiddle or similar. I guess that you have a list of objects that hold images or links and you want to put them together in some ng-repeat based on the type either show link or image.
So this would be your data object:
let contentObj = [{
fieldLink: {
fieldLinkNewTab: false,
fieldLinkHref: "www.etc.com",
fieldLinkText: "click here for random website",
}
}, {
fieldLink: {
fieldLinkNewTab: true,
fieldLinkHref: "www.etc.com",
fieldLinkImage: "https://images.pexels.com/photos/590490/pexels-photo-590490.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb",
}
}];
and this would be your html, if fieldLinkText is there it will show text, if fieldLinkImage is there it will show image, keep in mind if you have both it will show both, also by utilizing power of ng-attr-target you show one element in html and not two with ng-if:
<div class="links" ng-repeat="content in contentObj" ng-if="content.fieldLink">
<a ng-attr-target="{{(content.fieldLink.fieldLinkNewTab) ? '_blank' : undefined}}" ng-href="{{ content.fieldLink.fieldLinkHref }}">
<span ng-if="content.fieldLink.fieldLinkText">{{ content.fieldLink.fieldLinkText }}</span>
<img class="image-class" ng-if="content.fieldLink.fieldLinkImage" src="{{content.fieldLink.fieldLinkImage}}" alt="" />
</a>
</div>
I hope this is helpful, I didn't mean to be too critic, if I was sorry about that, but these things will help you in future. And here's the fiddle that you can play on change your data tweak it up a bit: https://jsfiddle.net/pegla/j392Lvdp/3/

click on hyperlinks in unit testing using protactor in angularjs

I am new in unit testing in angularjs. I read the tutorial from:
https://github.com/angular/protractor/blob/master/docs/tutorial.md.
I want to click on hyperlink but i dont know how can i achieve this.
Here is my code:
<li ng-repeat="menu in sidebarLinks" ng-if="menu.visible == true " ng-class="{active: isActive('/{{menu.action}}')}">
<a ng-href="#/{{menu.action}}" title="{{menu.name}}" ng-click="loadSubmenus(menu.action)" ng-class="{active: isActive('/{{menu.action}}')}">
<div class="icon {{menu.icon}}" ng-class="{active: isActive('/{{menu.action}}')}"></div>
<span>{{menu.name}} </span>
</a>
</li>
In unit testing:
describe('Protractor Demo App', function() {
browser.driver.get('https://localhost:8443/login.html');
browser.driver.findElement(by.id('name')).sendKeys('test');
browser.driver.findElement(by.id('password')).sendKeys('test');
browser.driver.findElement(by.id('login')).click();
});
After login url is https://localhost:8443/#/dash
After click on link url should be https://localhost:8443/#/hypera
Since your links won't work for anyone else because you're running it locally on your machine, I can only tell you the best way to do it.
If you're dealing with hyperlinks, you need to get the element that you've set with 'login'. I'm not seeing it in your HTML snippet so I can't give you the correct path.
If it was a basic hyperlink, you could find it easily by using something like:
element(by.linkText('login')).click()
If your login button's text is indeed 'login'. If it is something else, like a button, you'll need to find the exact element and it will look like:
element(by.css('span[class="login"]')).click()
If your login button is under a 'span' tag in your HTML page.

Ghost.py - click specific button

I'm trying to click specific button but with no result yet.
Using Python 3.4.2 and Ghost.py.
<a class="button" title="" ref="1" id="details" href="javascript:void(0);">
</a>
This code is under many div's and li's.
The simplest answer is welcomed!
You can evaluate a line of Javascript with Ghost.py and use the click method on the appropriate DOM element you get with getElementById:
page, resources = ghost.evaluate("document.getElementById('details').click();", expect_loading=True)
UPDATE
To get the link by class use the following line
ghost.evaluate("document.getElementsByClassName('button')[0].click();", expect_loading=True)
There is another version you can use to select and click the first link with an ref="1" attribute on your page:
ghost.evaluate("document.querySelector('a[ref="1"]').click();", expect_loading=True)

JQuery: select using markup tags?

I am dynamically finding the string of open tag within a page and want to use JQuery to get the text of the element that the open tag corresponds to.
For example, suppose this is my page:
<h1 class="articleHeadline">
<NYT_HEADLINE version="1.0" type=" ">
The Arab Awakening and Israel
</NYT_HEADLINE>
</h1>
<author id="monkey" class="mainauthorstyle">
<h6 class="byline">
By
<a rel="author" href="http://topics.nytimes.com/top/opinion/editorialsandoped
/oped/columnists/thomaslfriedma/index.html?inline=nyt-per" title="More Articles
by Thomas L.Friedman" class="meta-per">
THOMAS L. FRIEDMAN
</a>
</h6>
</author>
I find the '<author id="monkey" class= "mainauthorstyle">' open tag string, and want to get $("author" id["monkey"] class["mainauthorstyle"]).text() --> By THOMAS L. FRIEDMAN. Is there a simple way to turn the open tag markup into a selector? Should I just parse it with regex?
Edit: I don't know beforehand what element I want. My code looks through the page and comes up with '<author id="monkey" class= "mainauthorstyle">' as the beginning of the element. I don't know the literal beforehand. I run this code on arbitrary webpages.
author#monkey.mainauthorstyle
Here's how you do it: http://jsfiddle.net/peduarte/MgbCX/
I'm having a bit of trouble understanding your question. If you just want the text, use the following:
$("author#monkey.mainauthorstyle").text();
If you want to select the element only if "THOMAS L. FRIEDMAN" is the author, then:
$("author#monkey.mainauthorstyle:contains('THOMAS L. FRIEDMAN')")
// See http://api.jquery.com/contains-selector/ for more info on the :contains() selector
UPDATED AFTER YOUR EDIT:
If you are able to determine that you want to select the "text" of the author element with id of "monkey" and class of "mainauthorstyle", you simply need to build a jQuery selector out of those bits of information. From there you can use the text() or html() methods on the resulting jQuery object to get the contents of that element.
As my example above showed:
$("author#monkey.mainauthorstyle").text();
or
$("author#monkey.mainauthorstyle").html();
Note that the selector used is probably overkill as you should be able to simply select the element by its id.
$("#monkey").text();

Categories