Xpath by ID or class does not work - selenium

I am not able to run my selenium webdriver tests its not detecting xPath. I tried
driver.findElement(By.xpath(".//*[#id='manageEvents']")).click(); for the
below is HTML code:
<head>
<body style="height: 100%; background-color: aliceblue;">
<div class="container-fluid">
<div class="row">
<!-- Left Side Bar-->
<div class="col-md-3 col-xs-12">
<div class="row">
<div class="row leftMenu">
<div class="row leftMenu">
<div class="row leftMenu">
<div id="manageEvents" class="menuBlk">
<i class="fa fa-folder-open" style="font-size:68px;margin-top:20px" />
<h3 style="margin-top:0px">Manage Events</h3>
</div>
</div>
</div>
<!-- Feed -->
<div class="col-md-6 col-xs-12">
<!-- Right Side Bar -->
<div class="col-md-3 col-xs-12">
</div>
</div>
</body>
</html>
Any help would be appreciated.
Thanks!

You can try to wait until required element appears in DOM and become clickable:
WebElement element = (new WebDriverWait(driver, 10)).until(ExpectedConditions.elementToBeClickable(By.xpath(".//*[#id='manageEvents']")));
element.click();
or if your element located inside an iframe, you need to switch to that iframe before searching for element:
driver.switchTo().frame(driver.findElement(By.tagName("iframe")));
driver.findElement(By.xpath(".//*[#id='manageEvents']")).click();
P.S. If there are more than one iframe on page this code might not work, so provide HTML for target iframe to get exact selector for it

Try not to go down to the root of the tree and make
//*[#id="manageEvents"]

Related

How can I locate a parent of an element know by child value using CodeceptJS

basically I have the following:
<div class="container">
<div class="title">title 1</div>
</div>
<div class="container">
<div class="title">title 2</div>
</div>
<div class="container">
<div class="title">title 3</div>
</div>
I want to locate the container that has "title 2" as title, without Xpath Please. I mean just css selectors and codeceptJS functions. Is it possible to do it?
You can do:
locate(".container").withChild(".title").withText("title 2")
See the locator builder documentation for more info.

Selenium WebDriver click child element

I'm using selenium and I want to click a child element with 2 as value.
This is the full code:
<div class="dialer-keypad">
<div class="dialpad-row">
<div class="key">
<div class="value">1</div>
<div class="letters"></div>
</div>
<div class="key">
<div class="value">2</div>
<div class="letters">ABC</div>
</div>
<div class="key">
<div class="value">3</div>
<div class="letters">DEF</div>
</div>
</div>
<div class="dialpad-row">
<div class="key">
<div class="value">4</div>
<div class="letters">GHI</div>
</div>
<div class="key">
<div class="value">5</div>
<div class="letters">JKL</div>
</div>
<div class="key">
<div class="value">6</div>
<div class="letters">MNO</div>
</div>
</div>
</div>
So my question is How can I click this element?
<div class="value">2</div>
You should be able do this quite succinctly with XPath:
//*[contains(#class, 'value') and text()='2']
Alternatively, assuming that the markup was static you could target the element using specific indices. For example:
.dialpad-row:first-child .key:nth-child(2) .value
Simply use xpath
//div[contains (#class,'value') and contains (text(),'2')]

Bootstrap Profile Card

I'm trying to build a profile card in Bootstrap 3 and I'm having trouble getting the image to fit into the card. I think I can do this easier if I link to image in the css but I have many profile cards with all different people so I think keeping the image link in the HTML is better in this case.
Here's how I'd like it:
and here's the where I'm at:http://jsfiddle.net/L3789n7u/1/
Any help is greatly appreciated. Thanks!
~Tony
<div class="container">
<div class="row">
<div class="people-cards">
<div class="col-md-6">
<div class="well">
<div class="profile-image">
<img src="https://higherlogicdownload.s3.amazonaws.com/MBGH/4f7f512a-e946-4060-9575-b27c65545cb8/UploadedImages/Board%20Photos/SIZE%20150x190/PAMELA%20HANNON%202015.jpg">
<div class="card-info">
<h3 div class="company">Company Name</h3>
<h4 div class="name">Person Name</h4>
<h5 div class="title">Job Title</h5>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
As ever you have multiple options, here is example of one of them.
<div class="container">
<div class="row">
<div class="people-cards">
<div class="col-md-6" style="border: 1px solid black;">
<div class="row">
<div class="profile-image" style="float:left;">
<img src="https://higherlogicdownload.s3.amazonaws.com/MBGH/4f7f512a-e946-4060-9575-b27c65545cb8/UploadedImages/Board%20Photos/SIZE%20150x190/PAMELA%20HANNON%202015.jpg" />
</div>
<div class="profile-info">
<h3 div class="company">Company Name</h3>
<h4 div class="name">Person Name</h4>
<h5 div class="title">Job Title</h5>
</div>
<div class="profile-link">
VIEW PROFILE
</div>
</div>
</div>
</div>
</div>
</div>
Basically you need to make profile image to float left, so other content will appear next to it. Also because your example how you would like it contains border around card you need to wrap image, info and link in row. If you want to customize image size you can still use all Bootstrap's col-size-number.
Working example on JSFiddle

Selenium web driver: unable to locate element

I am New to selenium: I have this source and am trying click on a button using xpath with selenium webdriver. This is the button(last line in the html) that am trying to click on:
I use this xpath: "//div[#id='innerBody']/div[4]/div/div/ul/li[3]/button"
and it gives me unable to locate element.
Any idea why and how I should go about it.
<document>
<html class="FullPage" xmlns="http://www.w3.org/1999/xhtml" style="">
<head>
<body class="brand brand-mastwide FullPage no-footer width-hd" style="">
<div id="cboxOverlay" style="display: none;"/>
<div id="colorbox" class="" style="padding-bottom: 2px; padding-right: 2px; display: none;">
<div id="masthead" class="masthead full-width">
<div id="toast-absolute" class="full-width">
<!-- Content -->
<div id="outer-outer" class="with-nav">
<div id="outer-wrapper" class="full-width">
<a name="pageTop"/>
<div class="main-wrapper">
<div class="inner">
<div id="applicationHost">
<div data-bind="router: router" data-view="_App/AppShell" style="" data-active-view="true">
<div class="durandal-wrapper" data-view="_App/Home/HomeShell" style="" data-active-view="true">
<link rel="stylesheet" href="/cache/sf/_App/Home/HomeShell.css"/>
<link rel="stylesheet" href="/cache/sf/css/lib/joyride-2.1.css"/>
<div id="regionMain" class="clear-block with-side with-side-left" data-bind="css:{'clear-block with-side with-side-left': ShowLeftNavigation()}">
<div class="content-pane main">
<div class="inner-content-pane main">
<div data-bind="compose: Message"/>
<div class="router" data-bind="router: router">
<div class="durandal-wrapper" data-view="_App/Home/Filebox/Filebox" style="" data-active-view="true">
<h1 data-bind="text: Title">Bestandsvak voor satish vanahalli</h1>
<link href="/cache/f69bb3f534fb459062226526576bc4dea7e8fe7e/css/lib/jqui/jquery-ui-1.10.0.sf.css" type="text/css" rel="stylesheet"/>
<br/>
<div id="innerBody" class="file-box-container">
<div class="errortip" data-bind="text: ErrorMessage, visible: ErrorMessage" style="display: none;"/>
<div class="clear-block">
<div class="upload-button">
<div data-bind="compose: FileList">
<div class="c-content" data-view="_App/Home/Common/FileList/FileList" style="" data-active-view="true">
<div class="secondary-ctrl btnl-row title-noborder clear-block" data-bind="css: { hidden: !ShowSecondary }">
<ul class="context-actions" data-bind="visible: Capabilities.AllowCheckboxes, foreach: CurrentActions">
<li class="hover-list">
<li class="hover-list">
<li class="hover-list">
***<button class="txt context-action" data-bind="click: Click">***
Try this xpath:
//ul[#class='context-actions']/li[3]/button[#class='txt context-action][3]
As per your comments for question, if you want to click on the 3rd button in the list, please try below xpath; I have just tweaked #Saritha's :
(//button[#class='txt context-action'])[3]
This will click on the 3rd button in the page (in the chronological order of DOM representation) with class as txt context-action.
Try this xpath:
//*[#id="innerBody"]/div/div/div/div/div/div/ul/li[3]/button

Having some trouble understanding why the :contains() pseudo class in CSS selectors works the way it does?

I am using CSS selectors with Selenium and Cucumber. When a locator doesn't work I test it out using the console of the Chrome Developer Tools. I keep encountering a behavior I don't understand (as in why does it do what it is doing and not what I need it to do...). Please look at these locators:
div.view_header ~ div input.my_button
div:contains(My Header Title) ~ div input.my_button
div:contains(My Header Title) ~ div div div input.my_button
In my DOM the element matching the first part of each of those locators is the same...
<div class="view_header foo"> My Header Title </div>
The issue is that only locators #1 & #3 above will actually match anything. Does anybody know why this is true. I realize that div:contains(foo) will match not only the div that actually contains foo but all parent divs as well but it seems to me that the rest of the locator elements should be sorting it out so that it should work.
I'm just looking for any insight and possibly suggestions for a way to make sure that the 'my_button' I am clicking is the one under 'My Header Title' and not a 'my_button' somewhere else on the page (and the only easy way to distinguish them is by the header they are under) while eliminating the seemingly excess DOM structure in the locator so as to make it more likely to be reusable.
<head>
<body class="bp">
<div style="left: -100em; position: absolute; width: 100em;"></div>
<input class="refresh_marker" type="text" value="no" style="display:none">
<div class="container">
<div id="nav_bar">
<div id="user_bar">
<div id="wrapper" style="border-radius: 10px 10px 10px 10px;">
<div class="content">
<div class="page_title"> Title </div>
<div></div>
<a class="change_tracker_link"> </a>
<div class="breadcrumb_trail">
<style type="text/css">
<div id="dialog_no_new_assoc" class="hide" title="No Associations Selected"></div>
<div class="organizer_widget root_organizer" title="WorkflowItem" style="">
<input id="data_classifier" type="hidden" value="Workflow::WorkflowItem">
<input id="data_id" type="hidden" value="34">
<input id="data_getter" type="hidden">
<input id="collection_vertex_id" type="hidden" value="4cb1ecc300fa5f77844b1e87431d0a25390c1c77">
<input id="view-name" type="hidden" value="EnterPaperInformation">
<div class="object organizer">
<div class="clear"></div>
<div class="interior">
<form method="POST" enctype="multipart/form-data">
<input type="hidden" value="4cb1ecc300fa5f77844b1e87431d0a25390c1c77" name="vertex_id">
<input type="submit" value="Save" style="display: none;" name="submit_form">
<div class="organizer_header view_header"> My Header Title </div>
<div class="organizer_widget" title="Citation" style="">
<input id="data_classifier" type="hidden" value="Bibliography::Citation">
<input id="data_id" type="hidden" value="10">
<input id="data_getter" type="hidden" value="citation">
<input id="collection_vertex_id" type="hidden" value="5376dcc81102a5d76bf829513b096be8f67e560d">
<input id="view-name" type="hidden" value="CitationEntrySummary">
<div id="citation" class="object organizer">
<div class="clear"></div>
<div class="interior">
<div id="Citation___id_widget" class="widget_row numeric">
<div id="Citation___title_widget" class="widget_row string">
<div id="Citation___abbreviated_title_widget" class="widget_row string">
<div id="Citation___authors_display_string_widget" class="widget_row string">
<div id="Citation___language_widget" class="widget_row choice">
<div id="Citation___link_widget" class="widget_row link">
<input type="hidden" value="Bibliography::JournalArticle___10" name="check_5376dcc81102a5d76bf829513b096be8f67e560d[]">
<input id="ba_citation" class="my_button" type="button" value="Break Associations" name="break_assoc_5376dcc81102a5d76bf829513b096be8f67e560d">
<div class="clear"></div>
<input type="hidden" value="5376dcc81102a5d76bf829513b096be8f67e560d" name="vertices[]">
</div>
...
The usual thing I do when I find myself in this kind of trouble is to look at the spec.
As you probably know, there's none for :contains() in the current spec and therefore you rely on undocumented, unspeced features of a particular browser/parser. It should work, but it doesn't - obviously the implementation wasn't complete. And now the pseudo-class is gone.
Could you go for an XPath instead? Either by internal Selenium methods or JavaScript. This XPath is the same as your CSS selector number 2:
//div[contains(text(),'My Header Title')]/following-sibling::div//input[contains(#class,'my_button')]
EDIT
After your comment showed me that we're talking about Selenium RC and, therefore, Sizzle, I dug deeper.
I took your example HTML, stripped it from the hidden and (seemingly) needless elements, and was left with this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script src="sizzle.js" type="text/javascript"></script>
</head>
<body class="bp">
<div class="container">
<div id="nav_bar">
<div id="user_bar">
<div id="wrapper" style="border-radius: 10px 10px 10px 10px;">
<div class="content">
<div class="breadcrumb_trail">
<div class="organizer_widget root_organizer" title="WorkflowItem" style="">
<div class="object organizer">
<div class="interior">
<form method="POST" enctype="multipart/form-data">
<div class="organizer_header view_header"> My Header Title </div>
<div class="organizer_widget" title="Citation" style="">
<div id="citation" class="object organizer">
<div class="clear"></div>
<div class="interior">
<div id="Citation___id_widget" class="widget_row numeric">
<div id="Citation___title_widget" class="widget_row string">
<div id="Citation___abbreviated_title_widget" class="widget_row string">
<div id="Citation___authors_display_string_widget" class="widget_row string">
<div id="Citation___language_widget" class="widget_row choice">
<div id="Citation___link_widget" class="widget_row link">
<input id="ba_citation" class="my_button" type="button" value="Break Associations" name="break_assoc_5376dcc81102a5d76bf829513b096be8f67e560d" />
<div class="clear"></div>
</div></div></div></div></div></div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
I downloaded the latest Sizzle and I obtained the version of Sizzle that is actually used by Selenium in the current release.
Turns out those two are very different.
E.g. the contains implementation of current Sizzle:
return ~( elem.textContent || elem.innerText || getText( elem ) ).indexOf( match[3] );
and the implementation Selenium uses:
return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
I tried both implementations on my test document, results can be seen here (click to enlarge):
Current Sizzle - matches all perfectly
Selenium's Sizzle - matches 1 out of 4
The results say it all. Selenium uses an old version of Sizzle that is somehow imperfect in handling of :contains() pseudo-class. The current Sizzle version doesn't suffer from the bug and is able to find all elements well.
Now, you can do any of these:
File a Selenium bug.
Use XPath as a workaround.
Switch the sizzle.js file in your Selenium package.
#Selenium #Webdriver handle only HTML elements but with using java script executor It's possible to handle #pseudo elements in selenium #webdriver.
Ex: :after , :before etc
String script = "return window.getComputedStyle(document.querySelector('Enter root classname here'),':after / :before').getPropertyValue('content')";
Thread.sleep(3000);
JavascriptExecutor js = (JavascriptExecutor) driver;
String content = (String) js.executeScript(script);
System.out.println(content);