I am using selenium as a web scraper and would like to locate a number of tables and then for every table (by looping) locate an element inside that table (without going through the entire document again).
I am using the Iwebelement.FindElements(By.XPath) but keeps giving an error saying 'element no longer connected to DOM'
here is an excerpt from my code:
IList[IWebElement] elementsB = driver.FindElements(By.XPath("//*[#id=\"col_main\"]/table[#class='risultati']"));
// which loads all tables with class 'risultati'
foreach (IWebElement iwe in elementsB)
{
IList[IWebElement] ppp = iwe.FindElements(By.XPath("//table"));
}
here I am trying to load inner tables from inside each table found in elements, but keeps giving me the error mentioned above.
I believe the issue is with the double slashes in
IList[IWebElement] ppp = iwe.FindElements(By.XPath("//table"));
It shouldn't have any slashes so that the find begins with your iwe element. Double slashes mean look anywhere in the document.
should be
IList[IWebElement] ppp = iwe.FindElements(By.XPath("table"));
I would do it something like this:
By tableLocator = By.XPath("//table");
By itemLocator = By.XPath("//*[#id=\"col_main\"]/table[#class='risultati']");
for(WebElement iwe : elementsB) {
List<WebElement> tableList = iwe.FindElements( tableLocator );
for ( WebElement we : tableList ) {
we.getElementByLocator( itemLocator );
System.out.println( we.getText() );
}
}
public static WebElement getElementByLocator( final By locator ) {
LOGGER.info( "Get element by locator: " + locator.toString() );
final long startTime = System.currentTimeMillis();
Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring( StaleElementReferenceException.class ) ;
int tries = 0;
boolean found = false;
WebElement we = null;
while ( (System.currentTimeMillis() - startTime) < 91000 ) {
LOGGER.info( "Searching for element. Try number " + (tries++) );
try {
we = wait.until( ExpectedConditions.visibilityOfElementLocated( locator ) );
found = true;
break;
} catch ( StaleElementReferenceException e ) {
LOGGER.info( "Stale element: \n" + e.getMessage() + "\n");
}
}
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
if ( found ) {
LOGGER.info("Found element after waiting for " + totalTime + " milliseconds." );
} else {
LOGGER.info( "Failed to find element after " + totalTime + " milliseconds." );
}
return we;
}
Related
I am using htmlunit driver 2.36 getting error in "currentPage = orderStatus.setSelectedAttribute(option, true);"
error message:- Error during JavaScript execution com.gargoylesoftware.htmlunit.ScriptException after from catch exception is com.gargoylesoftware.htmlunit.TextPage cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlPage
HtmlPage currentPage = (HtmlPage) context.getVariables().get("currentPage");
DataRepository dr = (DataRepository) context.getVariables().get("dataRepository");
final WebClient webClient= currentPage.getWebClient();
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.waitForBackgroundJavaScript(3000);
List<String> alertmsgs = new ArrayList<String>();
CollectingAlertHandler alertHandler = new CollectingAlertHandler();
webClient.setAlertHandler(alertHandler);
try {
String remarks = dr.get("REMARKS");
if(StringUtils.isEmpty(remarks)){
remarks = "Please process the change request";
}
HtmlTextArea remarksText = currentPage.getElementByName("contactNewRemarks");
remarksText.setText(remarks);
String orderstatusOpt = "0";//dr.get("ORDERSTATUS");
HtmlSelect orderStatus = (HtmlSelect) currentPage.getElementByName("orderStatus");
logger.info("HtmlSelect Order Status: :: " + orderStatus);
for (HtmlOption option : orderStatus.getOptions()) {
logger.info("HtmlOption option: :: " + option.getValueAttribute());
if(option.getValueAttribute().equals(orderstatusOpt)) {
currentPage = orderStatus.setSelectedAttribute(option, true);
} else {
option.removeAttribute("selected");
}
}
I have a class that takes a String parameter and performs a google search, then it gets the ten images and puts them in an array, that is then handled by another method in the same class. Using Javafx.scene.image would probably allow me to implement the buffering progress easily, but there is a bug with JavaFX Image, that misinterprets the color encoding of normal Images, and saves a weird looking image to the hard drive, so I just decided to use awt.Image.
This is the image search class:
public class GoogleCustomSearch {
static String key = //custom google id;
static String cx = // also a custom google id;
static String searchType = "image";
static java.awt.Image[] publicImageArray;
public static java.awt.Image[] Search(String searchParameter,int start) throws IOException, URISyntaxException{
String formatedText = URLEncoder.encode(searchParameter,"UTF-8");
URL url = new URL("https://www.googleapis.com/customsearch/v1?" + "key=" +key + "&cx=" +cx + "&q=" +formatedText + "&searchType=" +searchType +"&imgSize=medium" + "&start=" + start + "&num=10");
System.out.println(url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
BufferedReader br = new BufferedReader(new InputStreamReader( ( conn.getInputStream() ) ) );
GResults results = new Gson().fromJson(br, GResults.class);
java.awt.Image [] imageArray = new java.awt.Image[10];
//JProgressBar prb = new JProgressBar();
//MediaTracker loadTracker = new MediaTracker(prb);
for(int i = 0; i<10; i++){
try {
imageArray[i] = ImageIO.read(new URL(results.getLink(i)));
}catch (java.io.IOException e){
imageArray[i] = ImageIO.read(new File("C:\\Users\\FILIP.D\\IdeaProjects\\Manual_Artwork\\src\\MAT - NoImage.jpg"));
}
}
conn.disconnect();
return imageArray;
}
public static BufferedImage getImage(String searchPar, int index, boolean newSearch) throws IOException, URISyntaxException {
int adaptedIndex;
int start;
BufferedImage bimage;
if(index<10){
adaptedIndex = index;
start = 1;
}else if (index<20){
start = 11;
adaptedIndex = index % 10;
if(index == 10){
publicImageArray = new java.awt.Image[10];
publicImageArray = Search(searchPar,start);
}
}else if(index < 30){
start = 21;
adaptedIndex = index % 10;
if (index == 20) {
publicImageArray = new java.awt.Image[10];
publicImageArray = Search(searchPar,start);
}
}else{
adaptedIndex = index % 10;
start = 21; //ovo ce posle 30 da ga vrti u loop prvih 10
}
if(newSearch){
publicImageArray = new java.awt.Image[10];
publicImageArray = Search(searchPar,start);
return bimage = (BufferedImage) publicImageArray[adaptedIndex];
}else{
return bimage = (BufferedImage) publicImageArray[adaptedIndex];
}
}
public static RenderedImage getLiveImage (int index){
return (RenderedImage) publicImageArray[index % 10];
}
}
And this is the snippet of the main GUI class that just handles opening the new image in the array
private void nextImageResult() throws IOException, URISyntaxException {
if(imgNr == -1){
imgNr++;
changeImage(SwingFXUtils.toFXImage(GoogleCustomSearch.getImage(oppenedTrack.getArtistName() + "+" + oppenedTrack.getTrackName(),imgNr,true),null));
}else{
imgNr++;
changeImage(SwingFXUtils.toFXImage(GoogleCustomSearch.getImage(oppenedTrack.getArtistName() + "+" + oppenedTrack.getTrackName(),imgNr,false),null));
}
}
To summarise, I need a proper way to show a progress bar in the place of the image before it loads, and it needs not to hang the UI, for which I can use Task. I can optimise the loading of the array with MediaTracker, so it can prioritize loading the first few images first.
Okay, I guess I'm stuck here. Can't get the values from the file to show in JOptionPane's message dialog box where it's enclosed within a while loop.
Right now I don't know which method of Input/Output stream to use to display all the data on this file which I believed to be serialized as UTF8??
Please tell me what to do and what things I missed since I'm new to java.io classes.
Also, the file StudentData.feu was just given to me. It's not that I don't want to research on my own because I already did, I'm just stuck. I read the Javadoc but I'm clueless right now.
import java.io.*;
import javax.swing.JOptionPane;
public class MyProj {
public void showMenu() {
String choice = JOptionPane.showInputDialog
(null, "Please enter a number: " + "\n[1] All Students" + "\n[2] BSCS Students" + "\n[3] BSIT Students"
+ "\n[4] BSA Students" + "\n[5] First Year Students" + "\n[6] Second Year Students" + "\n[7] Third Year Students"
+ "\n[8] Passed Students" + "\n[9] Failed Students" + "\n[0] Exit");
int choiceConvertedString = Integer.parseInt(choice);
switch(choiceConvertedString){
case 0:
JOptionPane.showMessageDialog(null, "Program closed!");
System.exit(1);
break;
}
}
DataInputStream myInputStream;
OutputStream myOutputStream;
int endOfFile = -1;
double grades;
int studentNo;
int counter;
String studentName;
String studentCourse;
public void readFile()
{
try
{
myInputStream = new DataInputStream
(new FileInputStream("C:\\Users\\Jordan's Pc\\Documents\\NetBeansProjects\\MyProj\\StudentData.feu"));
try{
while((counter=myInputStream.read()) != endOfFile)
{
studentName = myInputStream.readUTF();
studentCourse = myInputStream.readUTF();
grades = myInputStream.readDouble();
JOptionPane.showMessageDialog
(null, "StdNo: " + studentNo + "\n"
+ "Student Name: " + studentName + "\n"
+ "Student Course: " + studentCourse + "\n"
+ "Grades: " + grades);
}
}
catch(FileNotFoundException fnf){
JOptionPane.showMessageDialog(null, "File Not Found");
}
}/* end of try */
catch(EOFException ex)
{
JOptionPane.showMessageDialog(null, "Processing Complete");
}
catch(Exception e)
{
JOptionPane.showMessageDialog(null, "An error occured");
}
}
}
while((counter=myInputStream.read()) != endOfFile)
The problem is probably here. You're reading a byte and then throwing it away. It isn't likely that the file contains extra bytes like this that are intended to be thrown away. The correct loop would go like this:
try
{
for (;;)
{
// .... readUTF() etc
}
}
catch (EOFException exc)
{
// You've read to end of file.
}
// catch IOException etc.
I am using below function to call EAR_Encrypt_FTP.bat in C#. Is there any way to trace the echo messages dispayed in cmd.exe while running the batch file??
I need to process echo messages displayed on command prompt screen log the process.
private static short batchfileInvoke(string ftpFileName, string headerFile)
{
short value = 0;
Process p = null;
try
{
p = new Process();
ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = "cmd.exe";
string argument1 = "EAR_Encrypt_FTP.bat";
string test = "\"" + ftpFileName + "\"";
string argument2 = test;
string test1 = "\"" + headerFile + "\"";
string argument3 = test1;
p.StartInfo.WorkingDirectory = Path.GetDirectoryName(argument1);
startInfo.Arguments = "/C EAREncryptFTP.bat " + argument2 + " " + argument3;
p.StartInfo = startInfo;
p.Start();
p.WaitForExit();
int value2 = p.ExitCode;
value = (short)value2;
if(value==0)
{
Console.WriteLine("Encryption process is done");
}
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred :{0},{1}",
ex.Message, ex.StackTrace.ToString());
value = -4;
}
return value;
}
I have the next code:
var exeWindow = document.getElementById("exeWindow");
var errorWindow = document.getElementById("errorWindow");
var annot = editor.getSession().getAnnotations();
editor.getSession().on("changeAnnotation", execute);
function execute(){
exeWindow.innerHTML = eval(editor.getValue());
errorWindow.innerHTML = "";
annot = editor.getSession().getAnnotations();
for (var key in annot){
if (annot.hasOwnProperty(key))
console.log(annot[key].text + "on line " + " " + (parseInt(annot[key].row)+1));
errorWindow.innerHTML = annot[key].text + " Line " + " " + (parseInt(annot[key].row)+1);
exeWindow.innerHTML = "";
}
if (TogetherJS.running) {
TogetherJS.send({type: "execute"});
}
};
Im trying to capture the error logs, and before execute a valid code works, but once I introduce for example 2+2, despite of exeWindow changes correctly, if a rewrite it to 2+a for example, searching a new error, the exeWindow doesn´t changes and the error does not appears in errorWindow.
EDIT: Sorry, the problem is that is not getting the correct errors, only the errors like 'missing semicolon'.
If someone is interested, the solution I found is the next one:
function execute(){
try {
exeWindow.innerHTML = eval(editor.getValue());
errorWindow.innerHTML = "";
} catch(err){
var annot = editor.getSession().getAnnotations();
for (var key in annot){
if (annot.hasOwnProperty(key)){
errorWindow.innerHTML = annot[key].text + " Line " + " " + (parseInt(annot[key].row)+1);
exeWindow.innerHTML = "";
}
}
}
if (TogetherJS.running) {
TogetherJS.send({type: "execute"});
}
};
Simple as that :)