# Selenium - Notes 1
### 1. WebDriver object is inited by Test class and is assigned to Page class
### 2. Aware driver object becomes null in POM model
Might be due to the design which passes the incorrect driver object to the page object.
### 3. Use TestBase class, PageBase class
Or another way that applies more OOP and design patterns.
### 4. Invisible elements cannot be found when using `WebDriverWait ExpectedConditions.visibilityOfElementLocated`
For example, when sending the key to the file upload `input` tag.
### 5. When cannot locate elements
* Check if multiple windows, switch to that window: `Set<String> s = driver.getWindowHandles();`
* Check if the element is visible/ interactable
### 6. All the methods have a return value
Return current page or another page.
For example,

### 7. Locate the checkbox element
When cannot locate the `checkbox` element in the table row/ column, can try to click on the `tb` element which contains the target string.
### 8. When fail to locate elements
When fail to locate an element with a certain attribute (eg, class), try to locate by using different locating methods (eg, use `By.cssSelector` or `By.className` or `By.xPath`)
For example, locate button element:
This doe not work
```
private By applyBtn = By.className("applyBtn btn btn-sm btn-glow inverse");
```
But this works
```
private By applyBtn = By.cssSelector("button[class='applyBtn btn btn-sm btn-glow inverse']");
```
### 9. Handling Session timeout when obtaining data from an element for a long time
Increase the waiting time for the element to exist or be displayed.
### 10. Scrolling to the end of the page
```
// navigate to the page
driver.navigate().to("https://blog.testproject.io/2021/09/29/best-practices-for-testing-microservices/");
// send js to scroll to end
((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");
```
If does not work, can try scrolling to the element which is located at the page end instead.
### 11. Scrolling to element
If cannot scroll to certain elements, try to scroll to other elements on the same page, and return that element. And use **XPath Axes** to locate the target element.
Most common way:
```
WebElement element = driver.findElement(By.id("id_of_element"));
driver.executeScript("arguments[0].scrollIntoView(true);", element);
```
Another way that might work, refer to: https://medium.com/geekculture/best-way-to-use-scrollintoview-in-selenium-using-javascriptexecutor-f53518c5beed
```
WebElement element = driver.findElement(By.id("id_of_element"));
String script = "arguments[0].scrollIntoView({behavior: \"auto\", block: \"center\", inline: \"center\"});";
driver.executeScript(script, element);
```
### 12. Handling Select element (dropdown list)
Select an item in a multi-select element.
#### When the webpage is well designed
Solution: https://www.guru99.com/select-option-dropdown-selenium-webdriver.html
#### When the webpage is like shit or the Select element is not interactable (display: none)
Click on the parent element of it, and maybe add `Thread.sleep` to force sleep.
For example:

Solution:
Wait visible and with delay in between to make sure it stay.
```
public Pagination choosePerPage(final int count) {
waitAndClick(perPageSelectSpan);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getElementRemoveAttribute(waitVisible(perpage100), "unselectable").click();
return this;
}
```
#### Select item in dropdown when `unselectable="on"`
For example, solution: https://stackoverflow.com/questions/38751384/clicking-on-a-field-name-whose-unselectable-is-on-using-selenium
* 
* Wait a while and remove the attribute of the element
```
protected WebElement getElementRemoveAttribute(final WebElement element, final String attribute) {
((JavascriptExecutor) driver)
.executeScript("arguments[0].removeAttribute('" + attribute + "'); return arguments[0];", element);
return element;
}
```
### 13. Handling Web table
Refer to: https://www.lambdatest.com/blog/how-to-handle-web-table-in-selenium-webdriver/
* Get text in each td
## Issues
### Run multiple tests to get "SessionNotFoundException: Session ID is null. Using WebDriver after calling quit()?" (Not yet)
https://stackoverflow.com/questions/41352248/sessionnotfoundexception-session-id-is-null-using-webdriver-after-calling-quit
#### Solution:
Run testNG parallel.
### WebDriver object driver: java.lang.NullPointerException
#### Solution
Remove the extra driver variable in the Page class (Because the driver is already in the PageBase class, no need to have it in the Page class that extends PageBase class)
For example,
`SetupVersionPage` that extends `PageBase`

PageBase

###### tags: `selenium` `java` `test automation` `software test`