'Automation login test is failed, but login in web page is successful

I am trying to write automation tests for login page. The problem is that my code works as expected (web page is opened and I am logged in) but test is failed. When I trying to debug my code it says that I have problem with clickLoginButton() function but I have no idea what is wrong. Could you please help me? Thanks in advance!

Here is my class with elements and methods:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;

public class LoginData {

    private WebDriver driver;

    @FindBy(how = How.XPATH, using = "//a[@class = 'close-modal-window']/img")
    private WebElement close;

    @FindBy(how = How.XPATH, using = "//input[@id='email']")
    private WebElement emailField;
    @FindBy(how = How.XPATH, using = "//input[@id = 'password']")
    private WebElement passwordField;
    @FindBy(how = How.XPATH, using = "//app-submit-button/button[@class = "//button[@class = 'primary-global-button']")
    private WebElement loginButton;

    @FindBy(how = How.XPATH, using = "//*[@id='header_user-wrp']/li[1]/a")
    private WebElement userName;


    public LoginData(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    //("click on 'close' button")
    public LoginData clickCloseIcon() {
        close.click();
        return this;
    }

    //fill in Email
    public LoginData inputEmail(String emailInput) {
        emailField.click();
        emailField.clear();
        emailField.sendKeys(emailInput, Keys.ENTER);
        return this;
    }

    //input password | value = {passwordInput}
    public LoginData inputPassword(String passwordInput) {
        passwordField.click();
        passwordField.clear();
        passwordField.sendKeys(passwordInput, Keys.ENTER);
        return this;
    }

    // click on login button
    public LoginData clickLoginButton () {
        loginButton.click();
        return new LoginData(driver);
    }

    //check if element is displayed when user is logged in 
    public boolean userNameIsDisplayed() {
        return userName.isDisplayed();
    }


}

And my login test:

import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.After;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;



import java.time.Duration;

import static org.junit.Assert.*;

public class LoginDataTest {
    private WebDriver driver;

    final String BASE_URL = "https://ita-social-projects.github.io/GreenCityClient/#/";

    @BeforeEach
    public void beforeMethod() {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        driver.get(BASE_URL);
        driver.findElement(By.partialLinkText("Увійти")).click();

    }


    @ParameterizedTest
    @ArgumentsSource(EmailPasswordArgumentsProvider.class)
    public void loginTest(String email, String password) {
        try {
            LoginData login = new LoginData(driver);
            login.inputEmail(email).inputPassword(password).clickLoginButton();
           Assertions.assertTrue(login.userNameIsDisplayed());
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }


    @AfterEach
    public void AfterMethod() {
        driver.quit();
    }

}


Solution 1:[1]

Selenium should mimic human-like behavior. Meaning that you have to wait before clicking on elements, and wait before and after typing text in the web page.

// You have 2 ways to do this:
// 1. Just use sleep, for 0.3-1 seconds
Thread.Sleep(300);
// 2. use WebDriverWait:
WebDriverWait wait = new WebDriverWait(driver, 10);    
WebElement we = wait.until(ExpectedConditions.
elementToBeClickable("By.Css or By.Xpath");
we.click(); 

Finding an element and immediately clicking or typing text into it is a bad practice.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tal Angel