Webdriver
		> Controls the browser
	Setup class
		> WebdriverManager - Automatically manages our driver which is chrome driver
		> Create instance of driver driver = new chromeDriver();
		> Then use 'get' method to access the URL (Driver.get will wait till the URL is loaded, driver.navigate().to() does not wait for the page to be loaded, used when pahe is cached)
		> driver.close() closes only the current window on which Selenium is running automated tests. The WebDriver session, however, remains active. On the other hand, the driver. quit() method closes all browser windows and ends the WebDriver session. driver. close() : The close() method closes the currently focused window, quitting the driver if the current window is the only open window. If there are no windows open, it will error out.
	TestNG Assertions
		> Hard assert
			- Stops execution after failure and moves to next annotation
			- Good when we have 1 assert
		> Soft assert
			- Continue execution after failure and moves to next statement line
			- Good when test has more than 1 assert in the test
			- assertAll() at the end will check if any of the asserts during the test failed, and will fail your test with a proper summary
		> Types of Assertions
			- AsserTrue - Verifies condition is True
			- AssertFalse - Verifies condition is False
			- AssertSame - Verifies 2 objects refer to same object
			- AssertNotSame - Verifies 2 objects does not refer to same object
			- AssertNotNull - Verifies object is not Null
			- AssertEquels - Verifies actual and expected results
	Paramateriztion in TestNG
		> Requires a XML file for Parameter tag
		> Java class for @Parameters annotation
		> in the XML file, add the data you need for the test under Parameter Tag.
		> Class level data should be added under Suite > Class
		> Test level data should be added under Test level
		> In the Java class, you can add the data with the data name, next to the @Parameters annotation
	Take screenshot of Failed test
		> Class to use for capturing failed test - ITestResult
			Capture the test failure in the AfterMethod Annotation
			if (ITestResult.FAILURE == testResult.getStatus()) {
			TakesScreenshot screenshot = (TakesScreenshot) driver;
			File source = screenshot.getScreenshotAs(OutputType.FILE);
			File destination = new File(System.getProperty("user.dir") + "/Screenshots/FailedTests/" +
                testResult.getName()+".png");

	Dynamic Wait
		> Wait till a condition is complete before throwing a exception
		> Wait a element is avilable
		> Different waits
			Thread.sleep() - Not a selenium method
			Page load timeout - Sets  the wait time for a page to load
			Script timeout - Sets wait till javascript to execute
			Implicit wait - Instrust Webdriver to wait till all elements connected to the driver
			explicit wait - Pause execution untill time has expired OR Expected condition has met via webDriverWait class
			Fluent wait - Allows us to wait for element, Check for element, and ignore exception

		-> Explicit wait - WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
		-> Implicit wait - driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
		-> Fluent wait - Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
            .withTimeout(Duration.ofSeconds(30L))
            .pollingEvery(Duration.ofMillis(100))
            .ignoring(NoSuchElementException.class);

			WebElement element = wait.until(new Function<WebDriver, WebElement>() {
			public WebElement apply(WebDriver driver)