Reputation: 1
The following code is provided below:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;
public class BaseClass {
protected static ChromeDriver chromeDriver;
@BeforeEach
public void before() {
System.setProperty("webdriver.chrome.driver", System.getenv("CHROME_DRIVER"));
chromeDriver = new ChromeDriver();
chromeDriver.manage().window().maximize();
chromeDriver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
chromeDriver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
chromeDriver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
}
@AfterEach
public void after() {
chromeDriver.quit();
}
}
import org.openqa.selenium.*;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.*;
public class NotebookListPage {
private static NotebookListPage instance;
private ChromeDriver chromeDriver;
private WebDriverWait wait;
private Actions actions;
public Dictionary<String, List<PageItem>> onePageCatalog = new Hashtable<>();
private int currentPage = 0;
private NotebookListPage(ChromeDriver chromeDriver) {
this.chromeDriver = chromeDriver;
this.wait = new WebDriverWait(chromeDriver, 22);
wait.pollingEvery(Duration.ofSeconds(4));
wait.ignoring(NoSuchElementException.class);
this.actions = new Actions(chromeDriver);
}
public static synchronized NotebookListPage getInstance(ChromeDriver chromeDriver) {
if (instance == null) {
instance = new NotebookListPage(chromeDriver);
}
return instance;
}
private WebElement getLowPriceField() {
return chromeDriver.findElement(By.xpath("//div[@data-auto='filter-range-glprice']/descendant::span[@data-auto='filter-range-min']/descendant::input[@type='text']"));
}
private WebElement getHighPriceField() {
return chromeDriver.findElement(By.xpath("//div[@data-auto='filter-range-glprice']/descendant::span[@data-auto='filter-range-max']/descendant::input[@type='text']"));
}
private WebElement getLenovoButton() {
return chromeDriver.findElement(By.xpath("//label[@data-auto='filter-list-item-152981']/descendant::span[@class='_1Mp5C']"));
}
private WebElement getHPButton(){
return chromeDriver.findElement(By.xpath("//label[@data-auto='filter-list-item-152722']/descendant::span[@class='_1Mp5C']"));
}
private WebElement getRecommendation() {
return chromeDriver.findElement(By.xpath("//div[@data-grabber = 'SearchRecommendations']"));
}
private List<WebElement> getItems() {
return chromeDriver.findElements(By.xpath("//div[@data-apiary-widget-name = '@light/Organic']"));
}
private List<WebElement> getForward() {
return chromeDriver.findElements(By.xpath("//span[@class='_3e9Bd']"));
}
private WebElement getCurrentPage() {
return chromeDriver.findElement(By.xpath("//div/div[@class='Xe4rX _18sEx _3-NJO']"));
}
public void initFilters(String lowPrice, String highPrice) throws InterruptedException {
getLowPriceField().click();
getLowPriceField().sendKeys(lowPrice);
getHighPriceField().click();
getHighPriceField().sendKeys(highPrice);
getLenovoButton().click();
getHPButton().click();
}
public void Parsing() {
currentPage = currentPage + 1;
onePageCatalog.put(Integer.toString(currentPage), new ArrayList<>());
actions.moveToElement(getRecommendation()).perform();
for (int i = 0; i < getItems().size(); ++i) {
String name = getItems().get(i).findElement(By.xpath("//h3[@data-auto='snippet-title']")).getText();
String stringPrice = getItems().get(i).findElement(By.xpath("//span[@class='_3MgRl']")).getText().replaceAll("[^0-9]", "");
int price = Integer.parseInt(stringPrice);
onePageCatalog.get(Integer.toString(currentPage)).add(new PageItem(name, price));
}
if (!getForward().isEmpty()) {
getForward().get(0).click();
wait.until(d -> Integer.parseInt(getCurrentPage().getText()) != currentPage);
Parsing();
}
}
}
public class PageItem {
String name;
int price;
public PageItem(String name, int price) {
this.name = name;
this.price = price;
}
}
The meaning of the last part of the code is that when iterating the dictionary in the for loop, a web element is searched for on a web page and immediately converted to a string. However, in line "107", namely:
" String string Price = getItems().get(i).findElement(By.xpath("//span[@class='_3MgRl']")).getText().replaceAll("[^0-9]", "");"
StaleElementReferenceException is thrown. I can't understand how it may be possible. It is me second version of code, and in the end, I still come to the conclusion that I need to iterate the dictionary/map and parse it from the WebElement format to the String format.
If you can explain what the problem is and help me solve this problem, I will be very grateful!
in early versions of the program, before the for loop and in the loop itself, I refreshed the locator, but it didn't help either.
as far as I understand, the locator becomes irrelevant immediately after the search until it is converted to text. But I can't figure out how to fix it.
Upvotes: 0
Views: 38