Testing CEF-based one-page application and have some problems. So, my application can generate an output file in many different configurations that are available to choose from dependent on each other dropdown lists.
Trying to generate files for all possible options by simulating the appropriate clicking: display list select the first possible option -> the same with list2 -> the same with list3 again -> go forward -> export file -> go back to the beginning.
for (WebElement material : materialList) {
displayMaterialList.click();
material.click();
for (WebElement size : sizeList) {
displaySizeList.click();
size.click();
for (WebElement thickness : thicknessList) {
displayThicknessList.click();
thickness.click();
//Exporting file:
nextStepButton.click()
nextStepButton.click();
exportFileButton.click();
copyPasteText("filename" + "_" + currentDataTime);
previousStepButton.click();;
}
}
}
These loops work fine without exporting file fragment embedded in the deepest loop, used them to display combinations of all possible options. But when I added file naming and exporting fragment tests project threw out
StaleElementReferenceException just after generated file, at the start of the second iteration. I think it can't find thickness.click(); but don't know why.
according to Exception Doc Selenium
Common Causes
A stale element reference exception is thrown in one of two cases, the first being more common than the second:
The element has been deleted entirely.
The element is no longer attached to the DOM.
Please check that, and if can't see the html tha you are trying to test in pretty difficult give a appropiate answer.
Related
I have problem while trying to get focus on the latest new tab i'v opened with selenium web driver.
in some mysterious way, when i try to change between 2 tabs it works,
but when i'm trying to do this with 4 tabs it always get focus on the 3rd tab.
here is the code of the function that gets WebDriver element:
ArrayList tabs = new ArrayList(driver.getWindowHandles());
System.out.println(tabs);
System.out.println(tabs.get(tabs.size() -1));
driver.switchTo().window((String) tabs.get(tabs.size() - 1));
and here is the out put when i'm printing the tabs:
[CDwindow-(43C81B1D7B7C666BFBFB339971ADEE0F), CDwindow-(CDD5D45D021E698DD005BC2AD6201714), CDwindow-(33FB208B51A8DD5F7DB947C7B0BAB9DD), CDwindow-(4B50A8C4074BEDB41152003DED37FB32)]
CDwindow-(4B50A8C4074BEDB41152003DED37FB32)
as you can see the first row is the all the ArrayList.
and the second row is only the last tab that i want to get focus on.
am i missing something here??
I fail to see the issue.
tabs holds a list of handles (which may or may not be in the order you see them in the browser).
tabs.size() is returning 4 (4 tabs). so tabs.get(tabs.size() - 1)) is tabs.get(4 -1 ) or tabs.get(3).
Since java is 0-indexed, tabs.get(3) is the last tab. And looking at the output above is correct; CDwindow-(4B50A8C4074BEDB41152003DED37FB32).
Where is it going to the third tab; CDwindow-(33FB208B51A8DD5F7DB947C7B0BAB9DD)?
I find it easier to keep track of if you Map the windows to a name:
public static Map<String, String> tabs = new HashMap<String, String>();
With the first String being your own descriptor like "Admin", or "Facebook" and the second String is the WindowHandle. You will need to add the windows one by one to keep track of them.
tabs.put(handleName, handle);
But when you want to switch you can use:
driver.switchTo().window(tabs.get("Admin"));
And eliminate all confusion.
So, after a little bit of debugging - i just wrote an if statement the will stop on the page i want.
Set<String> handles = driver.getWindowHandles();
String currentHandle = driver.getWindowHandle();
for (String handle : handles) {
if (!handle.equals(currentHandle)) {
driver.switchTo().window(handle);
if(whatImLookingFor)
break;
}
}
the problem is solved for me, but i think it worth to try to understand this for future needs...
I am trying to automate testing with Selenium Webdriver without the need of xpath. I'm facing problem when the site is modified then xpath is being changed. For elements(like buttons, drop downs etc) which needs some action to be performed any how it needs xpath or someother things to identify that element. If I want to fetch data(table contents) from site to validate its excecution,then here I will need lots of xpaths to do so.
Is there a better way to avoid some xpaths?
Instead of using xpath, you can map the elements by css selectors, like this:
driver.findElement(By.cssSelector("css selector"), OR
by ID, like this:
driver.findElement(By.id("coolestWidgetEvah")).
There are much more than these 2. See Selenium docomentation
Steven, you basically have 2 choices the way I see it. One is to inject your own attributes (i.e qa attrib for instance) into your web elements which will never change. Please see this post, on how you can achieve this:
Selenium: Can I set any of the attribute value of a WebElement in Selenium?
Alternatively you can still use 'naked' xpath in order to locate your elements.
By 'naked' i mean generic, so not so specific.
Consider this element sitting below this:
div id="username"
input class="usernameField"
button type='submit
So, instead of locating it like this (which is specific/aggresive):
//div[#id='username']//input[#class='usernameField']//button[#type='submit']
you can use a more mild approach, omitting the specific values, like so:
//div[#id]//input[#class]//button[#type]
Which is less likely to break upon change. However, beware you need to be 100% sure that with the 2nd approach you are locating a unique element. In other, words if there are more than 1 buttons you might select the wrong one or cause a Selenium exception.
I would recommend this Xpath helper add-on for Chrome which highlights on the screen when your xpath is correct and also shows you how many elements match you Xpath (i.e. unique or not?)
xpath Helper
Hope the above, makes sense, don't hesitate to ask if it does not!
Best of luck!
Ofcoarse there are certain other ways without using id/xpath/CSS and even "sendKeys". The solution is to do that via Sikuli.
Things to do:
You have to download the Sikuli exe jar (sikulixsetup-1.1.0). (from https://launchpad.net/sikuli/+download)
Install the Sikuli exe jar which extracts the "sikulixapi" and adds to the PATH variable.
Add the External jar "sikulixapi" at project level through Eclipse.
Now take images of the elements where you want to pass some text or click.
Use the reference of the images in Selenium Java code to write text & perform clicks.
Here is a simple code to browse to "https://www.google.co.in/" move on to Login page & enter Emailid & Password without any xpath or sendkeys.
package SikuliDemo;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.sikuli.script.Pattern;
import org.sikuli.script.Screen;
public class SikuliDemoScript {
public static void main(String[] args) throws Exception
{
Screen screen = new Screen();
Pattern image1 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\gmailLogo.png");
Pattern image2 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\gmailSignIn.png");
Pattern image3 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\Email.png");
Pattern image4 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\EmailNext.png");
Pattern image5 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\Password.png");
Pattern image6 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\SignIn.png");
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.co.in/");
screen.wait(image1, 10);
screen.click(image1);
screen.wait(image2, 10);
screen.click(image2);
screen.type(image3, "selenium");
screen.click(image4);
screen.wait(image5, 10);
screen.type(image5, "admin123");
screen.click(image6);
driver.quit();
}
}
Let me know if this answers your question.
Using the below Code i am trying to double click a text field and edit it with a value.
The error occured when running the script says-
Heading
Exception in thread "main" org.openqa.selenium.NoSuchElementException:Unable to locate element: {"method":"id","selector":".//[#id='00N28000001bbuD']"}
Below is the set of code used-
WebElement Fieldvalue;
Fieldvalue= driver.findElement(By.xpath(".//*[#id='00N28000001bbuD_ilecell']"));
//Fieldvalue= driver.findElement(By.xpath(".//*[#id='00N28000001bbuD']"));
action.moveToElement(Fieldvalue).doubleClick().perform();
driver.findElement(By.id(".//*[#id='00N28000001bbuD']")).sendKeys("60000");
driver.findElement(By.xpath(".//*[#id='bottomButtonRow']/input[1]")).click();
You might observe one thing that the xpath used to find the element is different than the webelement where i want to perform the edit.
The reason for this is -
Fieldvalue= driver.findElement(By.xpath(".//*[#id='00N28000001bbuD_ilecell']"));
Helps me find the complete row
and
driver.findElement(By.id(".//*[#id='00N28000001bbuD']")).sendKeys("60000");
is the section in the above selected row where the edit should occur.
I did try keeping both the ids same, but in both the occassions the script failed.
Can anyone assist?
You're using By.id with an xpath locator, that's why it fails. Change this:
driver.findElement(By.id(".//*[#id='00N28000001bbuD']")).sendKeys("60000");
To this:
driver.findElement(By.xpath(".//*[#id='00N28000001bbuD']")).sendKeys("60000");
Or this:
driver.findElement(By.id("00N28000001bbuD")).sendKeys("60000");
I see cq:lastModified in the page property which gives me the User who modified the page at the latest. Is there any way to get the list of latest 10 users who modified the page ? Does AEM stores that kind of information at all?
Thanks!
When on the page in CQ, if you open the Information tab in the Sidekick you can view the Audit log — this will show you modification actions on the page, including page activation, e.g.:
I think this stores 15 entries by default (I'm not sure if that number is editable).
Alternatively, you can view the History log under $CQ_HOME/crx-quickstart/logs/history.log — this will show entries for View/Edit/Delete on individual nodes (so for example, you can see that a component was edited rather than just a page).
It can be rotated by date or size as per other CQ logs, & will show:
Timestamp
Action
Node
Node type
For example:
28.07.2014 15:59:05 VIEW admin [/content/dam/geometrixx/travel/train_platform_boarding.jpg] [dam:Asset,mix:versionable]
There is no OOTB way to do this.
But here is how you can try to achieve it :
1) Create Custom workflow with a custom process step.
In this workflow process step copy the cq:lastModifiedBy property value to a new custom property(lets call this lastModifiedUsers, which will be an array)
2) Now create a launcher which runs on modified for cq:PageContent node type. Use this launcher to trigger workflow created in step 1.
Now everytime you modify this page, the launcher will trigger the workflow which will copy the cq:lastModifiedBy property value to this custom property which is an array and save it in the path-path/jcr:content node.
Use AuditLog Interface from com.day.cq.audit package and you can use AuditLog object to invoke getLatestEvents(String[] categories, String path, int max) here specify the max as 10 .
you will receive an array of AuditLogEntry objects and from this array you can get all user id's.
I'm trying to develop a step plugin using Pentaho,
I used textVar() Input for listing the variables.
the problem is that the custom variables that created from the previous step aren't listed, so i tried to used environmentSubstitute(${var}) inside my code for fetching the variable's value, and no thing effected !.
so please guide me to the right way for listing the custom variables that created using the previous steps , for listing it inside textVar() input inside my custom step plugin.
After many days of testing , I succeeded of listing previous field names using the follwoing :
Combo wField = new Combo();
String[] inputFields = transMeta.getPrevStepFields(stepname).getFieldNames();
Arrays.sort(inputFields);
for (String fName : inputFields) {
wField.add(fName);
}
That's all :)