Question: For some reason selenium doesn't locate existing web elements
I'm trying to build a Whatsapp bot in java using selenium and java error I'm working on a function that shows on the screen the response of a recipient that got messaged by the bot earlier.
I found the class "_2wUmf _21bY5 message-in focusable-list-item" to be fitting as it shows incoming messages but when java error I try to search by class name it doesn't find anything, even tried to use css selector but still nothing.
How can I locate those elements and why does it happen?
My code:
import javax.swing.*; class Main extends JFrame { public static void main(String[] args) { new Main(); } public Main() { this.setTitle("Whatsapp bot"); this.setLayout(null); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); this.setResizable(false); this.setSize(Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT); this.add(new MainPanel(0, 0, Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT)); this.setVisible(true); } }
'
public class Constants { public static final int WINDOW_WIDTH = 1400; public static final int WINDOW_HEIGHT = 800; public static final int LABEL_WIDTH = 110; public static final int LABEL_HEIGHT = 30; public static final int SPACE_BETWEEN_BOXES = 30; public static final int SPACE_BETWEEN_LINES=20; public static final int TEXT_FIELD_WIDTH = 100; public static final int TEXT_FIELD_HEIGHT = 30; public static final int BUTTON_WIDTH = 100; public static final int BUTTON_HEIGHT = 30; public static final int SLEEP_TIME=30; public static final int ONE=1; public static final int TWO=2; public static final int THREE=3; public static final int FOUR=4; public static final int ONE_HUNDRED=100; public static final int MARGIN_FROM_TOP = 10; public static final int MARGIN_FROM_LEFT = 5; }
'
import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import javax.swing.*; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; public class MainPanel extends JPanel { private JButton openWhatsappButton; private JLabel loginSuccessful; private JTextField enterPhone; private JTextField enterMessage; private JLabel enterPhoneLabel; private JLabel enterMessageLabel; private JLabel whyIsThePhoneEmptyLabelOrInvalid; private JLabel whyIsTheMessageEmptyLabel; private JLabel messageSentLabel; private JLabel messageReadOrDeliveredLabel; private JLabel responseLabel; public String phoneNumberFormatValidationAndReformation(String givenPhoneNumber) { String ans = new String(); final int CORRECT_LENGTH_VERSION_A = 12; final String CORRECT_START_OF_PHONE_NUMBER_VERSION_A = "9725"; final int START = 0; final int END_VERSION_A = 4; final int CORRECT_LENGTH_VERSION_B = 10; final String CORRECT_START_OF_PHONE_NUMBER_VERSION_B = "05"; final int END_VERSION_B = 2; final int START_OF_REFORMATTED_VERSION_B_ORIGIN = 2; if ((CORRECT_LENGTH_VERSION_A == givenPhoneNumber.length()) && (CORRECT_START_OF_PHONE_NUMBER_VERSION_A.equals(givenPhoneNumber.substring(START, END_VERSION_A)))) { ans = givenPhoneNumber; } if ((CORRECT_LENGTH_VERSION_B == givenPhoneNumber.length()) && (CORRECT_START_OF_PHONE_NUMBER_VERSION_B.equals(givenPhoneNumber.substring(START, END_VERSION_B)))) { ans = CORRECT_START_OF_PHONE_NUMBER_VERSION_A + givenPhoneNumber.substring(START_OF_REFORMATTED_VERSION_B_ORIGIN); } return ans; } public MainPanel(int x, int y, int width, int height) { this.setLayout(null); this.setBounds(x, y, width, height); System.setProperty("webdriver.chrome.driver", "C:\\Users\\danie\\OneDrive\\Desktop\\chromedriver.exe"); ChromeDriver driver = new ChromeDriver(); driver.manage().window().minimize(); openWhatsappButton = new JButton("Send"); openWhatsappButton.setBounds(Constants.WINDOW_WIDTH / Constants.TWO - Constants.BUTTON_WIDTH / Constants.TWO, Constants.WINDOW_HEIGHT / Constants.TWO - Constants.BUTTON_HEIGHT / Constants.TWO, Constants.BUTTON_WIDTH, Constants.BUTTON_HEIGHT); this.add(openWhatsappButton); loginSuccessful = new JLabel("Logged in successfully!"); enterPhone = new JTextField(); enterPhone.setBounds(Constants.WINDOW_WIDTH / Constants.FOUR - Constants.TEXT_FIELD_WIDTH, Constants.WINDOW_HEIGHT / Constants.TWO - Constants.SPACE_BETWEEN_LINES * Constants.FOUR, Constants.TEXT_FIELD_WIDTH * Constants.TWO, Constants.TEXT_FIELD_HEIGHT); this.add(enterPhone); enterPhoneLabel = new JLabel("Enter a phone number: "); enterPhoneLabel.setBounds(enterPhone.getX() - Constants.ONE - Constants.FOUR * Constants.LABEL_WIDTH / Constants.THREE, enterPhone.getY(), Constants.FOUR * Constants.LABEL_WIDTH / Constants.THREE, Constants.LABEL_HEIGHT); this.add(enterPhoneLabel); whyIsThePhoneEmptyLabelOrInvalid = new JLabel("~You must enter a number..."); whyIsThePhoneEmptyLabelOrInvalid.setBounds(enterPhone.getX() + Constants.ONE + Constants.TEXT_FIELD_WIDTH * Constants.TWO, enterPhone.getY(), Constants.FOUR * Constants.LABEL_WIDTH, Constants.LABEL_HEIGHT); enterMessage = new JTextField(); enterMessage.setBounds(Constants.THREE * Constants.WINDOW_WIDTH / Constants.FOUR - Constants.TEXT_FIELD_WIDTH, Constants.WINDOW_HEIGHT / Constants.TWO - Constants.SPACE_BETWEEN_LINES * Constants.FOUR, Constants.TEXT_FIELD_WIDTH * Constants.TWO, Constants.TEXT_FIELD_HEIGHT); this.add(enterMessage); enterMessageLabel = new JLabel("Enter a message: "); enterMessageLabel.setBounds(enterMessage.getX() - Constants.ONE - Constants.LABEL_WIDTH, enterMessage.getY(), Constants.LABEL_WIDTH, Constants.LABEL_HEIGHT); this.add(enterMessageLabel); whyIsTheMessageEmptyLabel = new JLabel("~You must enter a message..."); whyIsTheMessageEmptyLabel.setBounds(enterMessage.getX() + Constants.ONE + Constants.TEXT_FIELD_WIDTH * Constants.TWO, enterMessage.getY(), Constants.TWO * Constants.LABEL_WIDTH, Constants.LABEL_HEIGHT); loginSuccessful.setBounds(Constants.WINDOW_WIDTH / Constants.TWO - Constants.LABEL_WIDTH, openWhatsappButton.getY() - Constants.TWO * Constants.SPACE_BETWEEN_LINES, Constants.TWO * Constants.LABEL_WIDTH, Constants.BUTTON_HEIGHT); messageSentLabel = new JLabel("Message sent"); messageSentLabel.setBounds(Constants.WINDOW_WIDTH / Constants.TWO - Constants.LABEL_WIDTH / Constants.TWO, openWhatsappButton.getY() + Constants.TWO * Constants.SPACE_BETWEEN_LINES, Constants.LABEL_WIDTH, Constants.LABEL_HEIGHT); messageReadOrDeliveredLabel = new JLabel("Message has been delivered"); messageReadOrDeliveredLabel.setBounds(Constants.WINDOW_WIDTH / Constants.TWO - Constants.LABEL_WIDTH, messageSentLabel.getY() + Constants.TWO * Constants.SPACE_BETWEEN_LINES, Constants.TWO * Constants.LABEL_WIDTH, Constants.LABEL_HEIGHT); responseLabel = new JLabel("No response yet"); responseLabel.setBounds(Constants.WINDOW_WIDTH / Constants.TWO - Constants.LABEL_WIDTH, messageSentLabel.getY() + Constants.FOUR * Constants.SPACE_BETWEEN_LINES, Constants.TWO * Constants.LABEL_WIDTH, Constants.LABEL_HEIGHT); openWhatsappButton.addActionListener(e -> { boolean toBraek = false; List<WebElement> messagesDoubleChecksBefore = null; boolean toContinue = true; if (enterMessage.getText().equals("") || enterMessage.getText() == null) { whyIsTheMessageEmptyLabel.setText("~You must enter a message..."); this.add(whyIsTheMessageEmptyLabel); repaint(); toContinue = false; } else { whyIsTheMessageEmptyLabel.setText(""); repaint(); } String phoneNumber = phoneNumberFormatValidationAndReformation(enterPhone.getText()); if (enterPhone.getText().equals("") || enterPhone.getText() == null) { whyIsThePhoneEmptyLabelOrInvalid.setText("~You must enter a number..."); this.add(whyIsThePhoneEmptyLabelOrInvalid); repaint(); toContinue = false; } else { if (phoneNumber.equals("") || phoneNumber == null) { whyIsThePhoneEmptyLabelOrInvalid.setText("~phone number invalid"); this.add(whyIsThePhoneEmptyLabelOrInvalid); repaint(); toContinue = false; } } if (toContinue) { driver.get("https://web.whatsapp.com/send?phone=" + phoneNumber); driver.manage().window().maximize(); try { Thread.sleep(Constants.SLEEP_TIME); } catch (InterruptedException ex) { ex.printStackTrace(); } boolean loggedIn = false; while (true) { if (!loggedIn) { try { if (driver.findElement(By.id("pane-side")).isEnabled()) { this.add(loginSuccessful); repaint(); loggedIn = true; } else { continue; } } catch (NoSuchElementException exception) { continue; } } if (loggedIn) { boolean triedToSend = false; try { if (driver.findElement(By.cssSelector("div[ title=\"loading messages…\"]")).isEnabled()) { System.out.println("massage loading"); continue; } } catch (NoSuchElementException exception) { } List<WebElement> messagesChecksBefore = null; try { System.out.println("message not loading anymore"); messagesDoubleChecksBefore = driver.findElements(By.cssSelector("span[data-icon='msg-dblcheck']")); messagesChecksBefore = driver.findElements(By.cssSelector("span[data-icon='msg-dblcheck']")); messagesChecksBefore.addAll(driver.findElements(By.cssSelector("span[data-icon='msg-check']"))); messagesChecksBefore.addAll(driver.findElements(By.cssSelector("span[data-icon='msg-time']"))); System.out.println(messagesChecksBefore.size()); } catch (NoSuchElementException exception) { } try { Thread.sleep(Constants.SLEEP_TIME); } catch (InterruptedException ex) { ex.printStackTrace(); } try { WebElement typingBox = driver.findElement(By.xpath("/html/body/div[1]/div/div/div[4]/div/footer/div[1]/div/span[2]/div/div[2]/div[1]/div/div[2]")); typingBox.sendKeys(enterMessage.getText()); driver.findElement(By.xpath("/html/body/div[1]/div/div/div[4]/div/footer/div[1]/div/span[2]/div/div[2]/div[2]/button/span")).click(); triedToSend = true; } catch (NoSuchElementException exception) { } try { Thread.sleep(Constants.ONE_HUNDRED * Constants.SLEEP_TIME); } catch (InterruptedException ex) { ex.printStackTrace(); } List<WebElement> messagesChecksAfter = null; try { messagesChecksAfter = driver.findElements(By.cssSelector("span[data-icon='msg-dblcheck']")); messagesChecksAfter.addAll(driver.findElements(By.cssSelector("span[data-icon='msg-check']"))); messagesChecksAfter.addAll(driver.findElements(By.cssSelector("span[data-icon='msg-time']"))); System.out.println(messagesChecksAfter.size()); } catch (NoSuchElementException exception) { } if (messagesChecksAfter.size() == Constants.ONE + messagesChecksBefore.size() && triedToSend) { this.add(messageSentLabel); repaint(); System.out.println("should paint the message sent label"); toBraek = true; } if (toBraek) { break; } else { System.out.println("reattempting to send..."); } } } AtomicReference<List<WebElement>> messagesInTimeOfReading = null; List<WebElement> effectivelyFinalMessagesDoubleChecksBefore = messagesDoubleChecksBefore; AtomicBoolean threadClosed = new AtomicBoolean(false); new Thread(() -> { while (true) { System.out.println("loops in thread"); List<WebElement> messagesDoubleChecksAfter = null; boolean toBreakThatLoop = false; try { messagesDoubleChecksAfter = driver.findElements(By.cssSelector("span[data-icon='msg-dblcheck']")); } catch (NoSuchElementException exception) { } if (messagesDoubleChecksAfter.size() > effectivelyFinalMessagesDoubleChecksBefore.size()) { toBreakThatLoop = true; WebElement lastDoubleCheck = messagesDoubleChecksAfter.get(messagesDoubleChecksAfter.size() - Constants.ONE); while (true) { if (lastDoubleCheck.getAccessibleName().equals("Read ") || lastDoubleCheck.getAccessibleName().equals("Read")) { messageReadOrDeliveredLabel.setText("Message has been read"); this.add(messageReadOrDeliveredLabel); repaint(); System.out.println("message was read"); try { messagesInTimeOfReading.set(driver.findElements(By.cssSelector("div[ class='_2wUmf _21bY5 message-in focusable-list-item']"))); } catch (NoSuchElementException exception){ } catch (NullPointerException exception2) { } try{ messagesInTimeOfReading.get().addAll(driver.findElements(By.cssSelector("div[class='_2wUmf.message-in.focusable-list-item']"))); } catch (NoSuchElementException exception){ } catch (NullPointerException exception2) { } break; } else { messageReadOrDeliveredLabel.setText("Message has been delivered"); this.add(messageReadOrDeliveredLabel); repaint(); } } if (toBreakThatLoop) { break; } } else { try { Thread.sleep(Constants.SLEEP_TIME); } catch (InterruptedException ex) { ex.printStackTrace(); } } } threadClosed.set(true); }).start(); this.add(responseLabel); int messagesInTimeOfReadingCount=0; messagesInTimeOfReading.get().size(); if (messagesInTimeOfReading!=null){ messagesInTimeOfReadingCount=messagesInTimeOfReading.get().size(); System.out.println("found incoming messages"); } int effectivelyFinalMessagesInTimeOfReadingCount = messagesInTimeOfReadingCount; new Thread(() -> { while (true) { if (threadClosed.get()) { List<WebElement> currentMessages = null; try { currentMessages=(driver.findElements(By.cssSelector("div[ class='_2wUmf _21bY5 message-in focusable-list-item']"))); } catch (NoSuchElementException exception){ } catch (NullPointerException exception2) { } try{ currentMessages.addAll(driver.findElements(By.cssSelector("div[class='_2wUmf.message-in.focusable-list-item']"))); } catch (NoSuchElementException exception){ } catch (NullPointerException exception2) { } int currentMessagesCount=0; if (currentMessages!=null){ currentMessagesCount=currentMessages.size(); } if (currentMessagesCount > effectivelyFinalMessagesInTimeOfReadingCount) { WebElement response = currentMessages.get(currentMessages.size() - Constants.ONE); String printToResponseLabel = "Response: " + response.getAccessibleName(); int textLength = printToResponseLabel.length(); responseLabel.setBounds(Constants.WINDOW_WIDTH / Constants.TWO - Constants.TWO * textLength, messageSentLabel.getY() + Constants.FOUR * Constants.SPACE_BETWEEN_LINES, Constants.FOUR * textLength, Constants.LABEL_HEIGHT); responseLabel.setText(printToResponseLabel); repaint(); break; } } } }).start(); } }); } }
9codings