I have been trying to get the text from various div and tables for some BDD's I am writing in Cucumber. Everytime I try to acquire anything from the frontend of the website I'm working on it just pulls nothing. I need to know what I specifically need to do to get this content.
The page element I'm trying to retrieve from is similar to this
<div id="statMsg" class="statusMsg">Your changes are saved.</div>
These are the 2 methods that are currently trying to retrieve the text from the div.
public WebElement savedText() {
return webdriver.findElement(By.className("statusMsg"));
public void UserClicksOnSave() throws InterruptedException {
daSave.saveOn().click();
daPage.savedText().getText();
Find the DIV by XPATH such that it contains the text you are looking for:
public WebElement savedText() {
String xpath = "//div[contains(#class, 'statusMsg'][contains(., 'Your changes are saved.')]";
return webdriver.findElement(By.xpath(xpath));
Selenium should implicitly wait for the DIV matching that class name, and containing the given text. The findElement method should return only when both conditions are true, which should combat race conditions in your test.
Related
I learn Selenium in Java and I'm struggling with little problem.
I'm working on handling dropdowns and to resolve my probelm I have to use Select class.
I wrote a selector:
#FindBy(css="#speed")
WebElement selectSpeed;
Then I wrote a method :
public SelectMenuPage selectRandomSpeed(){
getWaitForTheElement().untilElementIsPresentCss("#speed");
//webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(locator)));
Select select = new Select(selectSpeed);
select.selectByIndex(0);
return this;
}
The problem is that when I use Select class the code simply does not work and I receive:
org.openqa.selenium.ElementNotInteractableException: element not interactable:
Element is not currently visible and may not be manipulated
It works very well when, instead of using Select, I just put the selectors of all the wanted elements and just simply interact with them. Unfortunately, I have to use Select class.
Here is my DOM
As per the HTML, the html-select tag is having the style attribute set as display: none;.
Unless the element is visible within the HTML DOM Select() may not work properly.
I am working with a pre-defined field so you can only enter specific values and if you enter any other value (which is not mapped in database) then it throws error.
Now, I want to check for which values (from excel sheet), this field throws error but I am struggling to achieve this because the only things which changes in the DOM for invalid value is ::before. If it is invalid ::before will appear.
Example:
<label for="Broom" data-error="Please." class="active">::before</label>
When I came across this problem, I could not see any way of doing this through the WebDriver locator strategy like XPATH, CSS etc. We can only use this via Javascript. Something like this:
public String errorCheck() {
String script = "return window.getComputedStyle(document.querySelector('label[for=\\'Broom\\']'),':before').getPropertyValue('content')";
JavascriptExecutor js = (JavascriptExecutor)driver;
String content = (String) js.executeScript(script);
return content;
}
So, you can verify if it returns null for valid values. If you do more research around this, you will find you can do more validations as well i.e colour etc.
This is more from reference point of view.
I've been trying to practice with drag and drop tests on following page https://www.seleniumeasy.com/test/drag-and-drop-demo.html
Here is the code of PageObject class with only one method, which drags and drops element of the list to the dropzone:
public class DragAndDropDemoPage extends Page {
public DragAndDropDemoPage(WebDriver driver) {
super(driver);
navigateTo();
}
#Override
public void navigateTo() {
driver.get(Urls.DRAG_AND_DROP_PAGE_URL);
}
public void dragAndDropElementWithIndex(int index) {
List<WebElement> elements = findElementsByCss("span[draggable=true]");
new Actions(driver).dragAndDrop(elements.get(index), findElementByCss("div#mydropzone")).build().perform();
}
}
after performing of such an action WebDriver eventually navigates to the Google Search page. And search request contains the name of the element I've been dragging.
What's wrong with this case? How did WebDriver managed to move to another page?
PS: Super class Page is:
public abstract class Page {
WebDriver driver;
public Page(WebDriver driver) {
this.driver = driver;
}
public abstract void navigateTo();
protected WebElement findElementByCss(String cssSelector) {
return driver.findElement(By.cssSelector(cssSelector));
}
protected List<WebElement> findElementsByCss(String cssSelector) {
return driver.findElements(By.cssSelector(cssSelector));
}
protected WebElement findByXpath(String xpath) {
return driver.findElement(By.xpath(xpath));
}
}
As per the HTML you have shared the WebElement which you want to DragAndDrop() contains the attribute draggable=true
draggable
draggable is a attribute that indicates whether an element can be dragged, either with native browser behavior or the HTML Drag and Drop API. draggable can have the following values:
true: the element can be dragged.
false: the element cannot be dragged.
Note: This attribute is enumerated and not Boolean. A value of true or false is mandatory, and shorthand like <img draggable> is forbidden. The correct usage is <img draggable="false">.
If this attribute is not set, its default value is auto which means drag behavior is the default browser behavior: only text selections, images, and links can be dragged. For other elements, the event ondragstart must be set for drag and drop to work.
Native HTML5 Drag and Drop
Eric Bidelman in the article Native HTML5 Drag and Drop mentioned, making an object draggable is simple as you only need to set the draggable=true attribute on the element you want to make moveable. As an example:
<div id="cols">
<div class="col" draggable="true"><header>X</header></div>
<div class="col" draggable="true"><header>Y</header></div>
<div class="col" draggable="true"><header>Z</header></div>
</div>
To enable other types of content to be draggable you can leverage the HTML5 DnD APIs. However, using CSS3 you can spruce up the markup to look like columns and adding cursor gives users a visual indicator that something is moveable but most browsers will create a ghost image of the content being dragged and draggable won't do anything. Some browser, FF in particular will require that some data be sent in the drag operation.
Further, Remy Sharp in the article Dragging Anything mentioned:
The HTML 5 spec says it should be as simple as adding the following attributes to the markup of the elements in question:
draggable="true"
However, this doesn’t work completely for Safari or Firefox. For Safari you need to add the following style to the element:
[draggable=true] {
-khtml-user-drag: element;
}
This will start working in Safari, and as you drag it will set a default, empty value with the dataTransfer object. However, Firefox won’t allow you to drag the element unless you manually set some data to go with it.
Solution
To solve this, we need a dragstart event handler, and we’ll give it some data to be dragged around with:
var dragItems = document.querySelectorAll('[draggable=true]');
for (var i = 0; i < dragItems.length; i++) {
addEvent(dragItems[i], 'dragstart', function (event) {
// store the ID of the element, and collect it on the drop later on
event.dataTransfer.setData('Text', this.id);
});
}
References
A couple of references:
A working demo of drag and drop anything (source code)
Working example of Drag and Drop
Problem: source element is dropping to the mouse position and not to target element. Drag and drop works in other website, you can check here.
When you run script probably your mouse position is somewhere near tab bar of the browser, that's why google opens (same as you put drag any text to the browser bar).
You can try #DebanjanB solution or you can use Robot.
I'm designing tests in Selenium WebDriver Framwework and I would like to insert text into fields in login box.
Here is a website www.fitandjump-widzew.pl
After click on "Zaloguj" button in top right corner, Login box appears.
I would like to insert text into E-mail inputfield.
Here is my code:
WebElement emailInput = driver.findElement(By.xpath("//[#id=\"inputFields\"]"));
emailInput.click();
emailInput.sendKeys("grzegorzrudniak#gmail.com");
After execution I get this error:
org.openqa.selenium.ElementNotVisibleException: element not visible
Can anyone help me to insert text into this field?
Please take a look at second input in this box, it's called "Hasło".
Xpath of this two fields is the same.
Additional question is how to insert text into "Hasło" inputfield as well?
Just make sure the locator you are using identifies single element [Unique]. Use single quotes in xpath and use correct xpath, you haven't used any html tag after // I've used * which means it is valid for all HTML tags.
WebElement emailInput = driver.findElement(By.xpath("//*[#id='inputFields']"));
//emailInput.click(); // no need to click on the element, you can directly type.
emailInput.sendKeys("grzegorzrudniak#gmail.com");
I would like to get the value of all div tags specified in attached. I have tried with all possible locators like classname etc, which is showing null. and tried with JavaScript also which is returning null.
Please see the screen shot and I need the selected text which is in blue color starts with "Enables enterprise IT to deploy networking services"
You need to research creating selectors as this isn't a difficult one. There are numerous approaches for this element, but here's one for you: $$("#offers-popover .description"). Obviously this is a CSS selector based on the $$ and you use getText from the Selenium API in order to scrape the element text, which is what I assume you are intending to do.
driver.findElement(By.css("#offers-popover .description")).getText();
Since your element is not visible you can try this:
String divText = driver.findElement(By.className("description")).getAttribute("textContent");
Or, if this is not the only element on the page with the class description:
WebElement popElement = driver.findElement(By.id("offers-popover"));
String divText = popElement.findElement(By.className("description")).getAttribute("textContent");