On using @Findby annotation, I suggest you go with object repository where all the web-element address is located all at one place. It's easier and maintainable.
For a small/medium project, try to store the web-element address in a property/(.ini) file, where you can mention web-element locator type (like xpath, id, classname etc,) and web-element locator value (like //input[@id='username']
Eg.: Login_page_btn_username = xpath:>://input[@id='username']
############################### Login PAGE ###################################################################
[LOGINPAGE]
LP_txtbx_username = id:>:login-email
LP_txtbx_password = xpath:>://input[@id='login-password']
LP_btn_submit = xpath:>://input[@id='login-submit']
LP_txt_invalid_login = xpath:>://strong[contains(text(),'There were one or more errors in your submission. ')]
And you can create a customized function to retrieve locator type and
value by calling function, and use it whenever the driver is
performing a click, send_keys() operations.
from selenium.webdriver.common.by import By
import configparser
def locator(web_element_name):
try:
global web_element
config = configparser.ConfigParser()
config.read("/home/vinod/automation/learn/Utilities/obj_repo.ini") # ini file path
for section in config.sections():
for lines in config.items(section):
if lines[0].lower() == web_element_name.lower():
web_element = lines[1]
locator_type = web_element.split(':>:')[0]
locator_value = web_element.split(':>:')[1]
if locator_type.strip().lower() == "id":
return [By.ID, locator_value]
elif locator_type.strip().lower() == "xpath":
return [By.XPATH, locator_value]
elif locator_type.strip().lower() == "linktext":
return [By.LINK_TEXT, locator_value]
elif locator_type.strip().lower() == "partiallinktext":
return [By.PARTIAL_LINK_TEXT, locator_value]
elif locator_type.strip().lower() == 'name':
return [By.NAME, locator_value]
elif locator_type.strip().lower() == "tagname":
return [By.TAG_NAME, locator_value]
elif locator_type.strip().lower() == "claasname":
return [By.CLASS_NAME, locator_value]
elif locator_type.strip().lower() == 'css':
return [By.CSS_SELECTOR, locator_value]
except Exception as e:
print("Method locator | Exp Desc: ", e)
assert False
And create a test base class to perform selenium action as click,
send_keys all in once class.
from selenium import webdriver
from Utilities.obj_property import locator
def activate_driver(browser_name):
try:
if browser_name.strip().lower() == 'chrome':
driver = webdriver.Chrome()
print("Chrome WebDriver is initialized.")
return driver
except Exception as e:
print("activate_driver | Exp Desc: ", e)
assert False
def open_url(driver, url):
try:
driver.get(url)
print("Application URL: " + url + " is successfully opened.")
except Exception as e:
print("open_url | Exp Desc: ", e)
assert False
def maximize_window(driver):
try:
driver.maximize_window()
print("Browser window is now maixmized.")
except Exception as e:
print("maximize_window | Exp Desc: ", e)
assert False
def click(driver, web_ele):
try:
driver.find_element(locator(web_ele)[0], locator(web_ele)[1]).click()
print("Clicked on weblement " + web_ele + " successfully.")
except Exception as e:
print("click | Exp Desc: ", e)
assert False
def send_keys(driver, web_ele, value):
try:
driver.find_element(locator(web_ele)[0], locator(web_ele)[1]).clear()
driver.find_element(locator(web_ele)[0], locator(web_ele)[1]).send_keys(value)
print("value " + value + " is successfully inputed into the " + web_ele + " field.")
except Exception as e:
print("send_keys | Exp Desc: ", e)
assert False
def get_text(driver, web_ele):
try:
return driver.find_element(locator(web_ele)[0], locator(web_ele)[1]).text
except Exception as e:
print("get_text | Exp Desc: ", e)
As we are following page object model, create a model for login page
(in your case) it would filling out form.
from Utilities import test_base
import time
def login(driver, url, username, password):
try:
test_base.open_url(driver, url)
test_base.maximize_window(driver)
test_base.send_keys(driver, "LP_txtbx_username", username)
test_base.send_keys(driver, "LP_txtbx_password", password)
test_base.click(driver, "LP_btn_submit")
time.sleep(5)
if driver.current_url == 'https://www.linkedin.com/feed/':
return True
else:
test_base.get_text(driver, "LP_txt_invalid_login") == "There were one or more errors in your submission. "
return False
except Exception as e:
print("login | Exp Desc: ", e)
finally execute test cases (here i'm using pytest)
from Utilities import test_base
from POM import login_page
import pytest
BROWSER = 'Chrome'
URL = "https://www.linkedin.com/"
@pytest.fixture(scope='function')
def driver():
return test_base.activate_driver(BROWSER)
def test_001_login_with_right_credential(driver):
assert login_page.login(driver, URL, "right_email_id", "right_password") is True
def test_002_login_with_incorrect_credential(driver):
assert login_page.login(driver, URL, "right_email_id", "incorrect_password") is False
Run the command: pytest test_execute.py
Output would look something like this.

More detailed step by step process, check out this article -
https://www.linkedin.com/pulse/how-build-simple-object-repository-selenium-webdriver-kouthal
if you are coding in java, I don't it should be a problem, just understand the workflow and implement in Java. Also, check out this link - http://toolsqa.com/selenium-webdriver/object-repository-in-selenium/ which uses Java.
Hope this helps.