package MockitoDemo.MockitoDemo;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.stream.Stream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import static org.junit.jupiter.params.provider.Arguments.arguments;
@Execution(ExecutionMode.CONCURRENT)
public class CrossbrowserDemo {
String username = "YOUR_USER_NAME";
       String accesskey = "YOUR_ACCESS_KEY";
   
      static RemoteWebDriver driver = null;
      String gridURL = "@hub.lambdatest.com/wd/hub";
      String urlToTest = "https://www.lambdatest.com/";
   
      @BeforeAll
      public static void start() {
          System.out.println("=======Starting junit 5 tests in LambdaTest  Grid========");
      }
   
      @BeforeEach
      public void setup(){
          System.out.println("=======Setting up drivers and browser========");
      }
   
      public void browser_setup(String browser) {
          System.out.println("Setting up the drivers and browsers");
          DesiredCapabilities capabilities = new DesiredCapabilities();
   
          if(browser.equalsIgnoreCase("Chrome")) {
              capabilities.setCapability("browserName", "chrome");    //To specify the browser
              capabilities.setCapability("version", "70.0");        //To specify the browser version
              capabilities.setCapability("platform", "win10");        // To specify the OS
              capabilities.setCapability("build", "Running_Junit5Tests_In_Grid_Chrome");               //To identify the test
              capabilities.setCapability("name", "JUnit5Tests_Chrome");
              capabilities.setCapability("network", true);        // To enable network logs
              capabilities.setCapability("visual", true);            // To enable step by step screenshot
              capabilities.setCapability("video", true);            // To enable video recording
              capabilities.setCapability("console", true);            // To capture console logs
          }
          if(browser.equalsIgnoreCase("Firefox")) {
              capabilities.setCapability("browserName", "Firefox");  //To specify the browser
              capabilities.setCapability("version", "76.0");    //To specify the browser version
              capabilities.setCapability("platform", "win10");   // To specify the OS
              capabilities.setCapability("build", "Running_Junit5Tests_In_Grid_Firefox");    //To identify the test
              capabilities.setCapability("name", "JUnit5Tests_Firefox");
              capabilities.setCapability("network", true);      // To enable network logs
              capabilities.setCapability("visual", true);       // To enable step by step screenshot
              capabilities.setCapability("video", true);        // To enable video recording
              capabilities.setCapability("console", true);      // To capture console logs
   
          }
          if(browser.equalsIgnoreCase("Safari")) {
              capabilities.setCapability("browserName", "Safari");  //To specify the browser
              capabilities.setCapability("version", "14.0.2");    //To specify the browser version
              capabilities.setCapability("platform", "macOS Big Sur");   // To specify the OS
              capabilities.setCapability("build", "Running_Junit5Tests_In_Grid_Safari");    //To identify the test
              capabilities.setCapability("name", "JUnit5Tests_Firefox");
              capabilities.setCapability("network", true);      // To enable network logs
              capabilities.setCapability("visual", true);       // To enable step by step screenshot
              capabilities.setCapability("video", true);        // To enable video recording
              capabilities.setCapability("console", true);      // To capture console logs
   
          }
          try {
              driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
          } catch (MalformedURLException e) {
              System.out.println("Invalid grid URL");
          } catch (Exception e) {
              System.out.println(e.getMessage());
          }
   
      }
   
      @ParameterizedTest
      @MethodSource("browser")
      public void launchAndVerifyTitle_Test(String browser) {
          browser_setup(browser);
          String methodName = Thread.currentThread()
                  .getStackTrace()[1]
                  .getMethodName();
          driver.get(urlToTest);
          driver.manage().window().maximize();
          driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
          String actualTitle = driver.getTitle();
          System.out.println("The page title is "+actualTitle);
          String expectedTitle ="Most Powerful Cross Browser Testing Tool Online | LambdaTest";
          System.out.println("Verifying the title of the webpage started");
          Assertions.assertEquals(expectedTitle, actualTitle);
          System.out.println("The webpage has been launched and the title of the webpage has been veriified successfully");
          System.out.println("********Execution of "+methodName+" has ended********");
      }
   
      @ParameterizedTest
      @MethodSource("browser")
      public void login_Test(String browser) {
          browser_setup(browser);
   
          String methodName = Thread.currentThread()
                  .getStackTrace()[1]
                  .getMethodName();
          driver.get(urlToTest);
          driver.manage().window().maximize();
          driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
          WebElement login = driver.findElement(By.xpath("//a[text()='Login']"));
          login.click();
          WebElement username = driver.findElement(By.xpath("//input[@name='email']"));
          WebElement password = driver.findElement(By.xpath("//input[@name='password']"));
          WebDriverWait wait = new WebDriverWait(driver,20);
          wait.until(ExpectedConditions.visibilityOf(username));
          username.clear();
          username.sendKeys("ruchirashukla89@gmail.com");
          password.clear();
          password.sendKeys("ruchira@89");
          WebElement loginButton = driver.findElement(By.xpath("//button[text()='Login']"));
          loginButton.click();
          driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
          String actual = driver.getTitle();
          String expected = "Welcome - LambdaTest";
          Assertions.assertEquals(expected, actual);
          System.out.println("The user has been successfully logged in");
          System.out.println("********Execution of "+methodName+" has ended********");
      }
   
      @ParameterizedTest
      @MethodSource("browser")
      public void logo_Test(String browser) {
          browser_setup(browser);
          String methodName = Thread.currentThread()
                  .getStackTrace()[1]
                  .getMethodName();
          System.out.println("********Execution of "+methodName+" has been started********");
          System.out.println("Launching LambdaTest website started..");
          driver.get(urlToTest);
          driver.manage().window().maximize();
          driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
          System.out.println("Verifying of webpage logo started..");
   
          WebElement logo = driver.findElement(By.xpath("//*[@id=\"header\"]/nav/div/div/div[1]/div/a/img"));
          boolean is_logo_present = logo.isDisplayed();
          if(is_logo_present) {
              System.out.println("The logo of LambdaTest is displayed");
          }
          else {
              Assertions.assertFalse(is_logo_present,"Logo is not present");
          }
          System.out.println("********Execution of "+methodName+" has ended********");
      }
   
      @AfterEach
      public void tearDown() {
          System.out.println("Quitting the browsers has started");
          driver.quit();
          System.out.println("Quitting the browsers has ended");
      }
   
      @AfterAll
      public static void end() {
          System.out.println("Tests ended");
      }
   
      static Stream<Arguments> browser() {
          return Stream.of(
                  arguments("Chrome"),
                  arguments("Firefox"),
                  arguments("Safari")
          );
      }
  
}