I'm trying to build a Whatsapp bot in java using selenium and 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 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();
}
});
}
}