How can we cal an object selenium to the other file which has half code of selenium.
In PHP i can by following code.
login($this); ----> login($sel){ ..... }
Can i do the same in Java as my selenium setup is in one file and the function which uses it is in another file can we pass the selenium to other as I am getting the NullPointerException.
Let me know if you want more details related to this.
Update
Library.java
public class Library extends SeleneseTestCase {
public int Login() throws Exception {
if (selenium.isElementPresent("companyID")) {
selenium.type("companyID", "COMP");
selenium.click("submit_logon");
selenium.waitForPageToLoad("80000");
}
}
}
Login.java
public class Login extends Library {
#Before
public void setUp() throws Exception {
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "https://businessbanking.com/");
selenium.start();
}
public void testAllTests() throws Exception {
Library obj1 = new Library();
obj1.Login();
}
}
As per my observation selenium instance started on login file is not addressed to Library. I tried to pass "selenium" as parameter but failed, in Library i tried "super.setUp()" it also failed.
Thanks.
Replace:
public void testAllTests() throws Exception {
Library obj1 = new Library();
obj1.Login();
}
With:
public void testAllTests() throws Exception {
super.Login();
}
Since your Login class already extends Library it already has the Login() method present in it. What you are currently doing is creating a new Library object which does not run the #Before and hence the Selenium field is not initialised (in the new object).
When a subclass extends a base class it will inherit its methods. This is a fundamental Java and OOP concept.
Related
Main Block:
public class test3 extends utility {
public WebDriver driver;
#BeforeTest
public void invokeBrowser() throws IOException {
driver = base();
driver.get(resource.getProperty("url"));
}
#Test
public class thirdPage {
public void main() {
actionTest test3 = new actionTest();
test3.executeTest();
}
}
}
Code performing mouse Actions:
public class actionTest {
public void executeTest() {
Actions execute = new Actions();
execute.moveToElement(driver.findElement(By.id("header-search-input"))).click().keyDown(Keys.SHIFT).sendKeys("Cricket").build().perform();
driver.findElement(By.id("header-desktop-search-button")).click();
}
}
Above code results in "NullPointerException" stating driver = null while executing block test3.executeTest();
Restructuring your codebase might help you to fix this issue. Create a base test class. Add the code related to web driver initialization and other main things there. Then create another class for your tests. Inherit it from the base test class. Then you can use the initialized driver in your all test classes.
I am using Testng for parallel execution of my web testcase. Totally i am having 5 classes.
BaseClass - for initializing and closing of my browser
Core class - Mediator for all drivers initialized
Reusable methods - Click, settext, gettext... [extends Step #2 Core class, so driver comes from there only]
Page Object Class - To store all locators like name,ID,xpath.Uses all those reusable methods like click, gettext,settext.
Main Test Class.
Base Class
public class TestNGBase {
ThreadLocal<WebDriver> localdriver = new ThreadLocal<>();
#BeforeMethod
public void initialize(){
System.setProperty("webdriver.chrome.driver","C:\\SeleniumTest\\chromedriver.exe");
localdriver.set(new ChromeDriver());
}
public WebDriver driver(){
Core.setDriver(localdriver.get());
return localdriver.get();
}
#AfterMethod
public void teardown(){
localdriver.get().close();
localdriver.remove();
}
}
Core Class:
public class Core {
protected static WebDriver driver;
public static void setDriver(WebDriver driverr) {
driver = driverr;
}
}
Reusable Class:
public class WebMethods extends Core {
public WebMethods() {
}
public static void Click(By by) {
driver.findElement(by).click();
}
PageObject Class
public class pagemethods(){
By login = By.name("login");
public void login(){
WebMethods.click(login);}
}
MainTestclass1 : Will use above Pageobject
MainTestclass2 : Will use above Pageobject
MainTestclass3 : Will use above Pageobject
So in above 3 testcase when i trigger all those using testng.xml file. 3 new browser gets initialized and it successfully opens the url. But when i start using the all those reusable methods such as click(). Out of 3 Testcase, any of the two testcase is always getting failed.
I think problem starts Core class as it receives all drivers at the same time. It's collapsing something.
Can some one help me to solve this parallel execution failure problem.
Thanks
Try to not make the main class static. Create a class that makes an instance of the class and then executes. When you make a static class, the method is hanging off of that class, not an instance.
E.g.
public WebDriver
{
WebDriver myWebDriver = new WebDriver();
myWebDriver.whateverMethod();
}
When using threads avoid static. Try that first.
I'm working on a project that uses JavaFX for the GUI (I know, non-serializable). I want to serialize objects such as my Users.
I'm not able to access the instance that JavaFX Application uses, but I have it associated in other classes.
For example - it is associated with my Controller class:
public class MyApp extends Application {
public void start(Stage stage){
// ... assume controller loaded
controller.setApp(this);
}
}
public class Controller {
MyApp app;
public setApp(MyApp app){
this.app = app
}
}
Now when I go to serialize an instance of MyApp, I'm having difficulty. I found a slight trick (option 1), but it feels a little messy. I'd much rather do option 2.
Option 1 [WORKS] - create an additional instance in the main method.
public class MyApp extends Application {
public void start(Stage stage){
// ... assume controller loaded
controller.setApp(this);
}
public static void main(String[] args){
MyApp app = new MyApp(); // this is a different instance than javafx instance.
launch(args)
app.users = Controller.getUsers();
writeApp(app);
}
public static void writeApp(PhotoApp photoApp) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new
FileOutputStream(storeDir + File.separator + storeFile));
oos.writeObject(photoApp);
oos.close();
}
}
Thus, option 1 essentially creates a new instance and copies stuff back and forth from the actual instance in controller.
OPTION 2 [DOES NOT WORK] - serialize the instance associated with the controller (since that is the actual instance JavaFX is using)
public class Controller {
MyApp app;
public void setApp(MyApp app){
this.app = app
}
public void someAction(){
MyApp.writeApp(this.app);
}
}
When I do Option 2 I get errors saying Controller is not serializable. I understand that it is not (which is okay), but I don't get that error in Option 1. In both options I'm calling the same method with some instance of MyApp. I'm not sure why it works for Option 1 but not Option 2.
Any reason why one option works over the other? How do most people do serialization of some of their objects when they use JavaFX?
Just pitching into Java! Trying to implement BDD style framework...
I'm running into this issue
My Driver.java looks like this:
public class Driver {
public static WebDriver Instance;
#Before
public void InitializeTest() {
System.setProperty("webdriver.chrome.driver", "C://chromedriver.exe");
Instance = new ChromeDriver();
}
#After
public void TearDownTest(Scenario scenario) {
//close the browser
if (scenario.isFailed()) { //take Screenshot
System.out.println(scenario.getName());
}
Instance.close();
}
}
And my Step-definition file:
public class MyStepdefs {
public static String Url = "https://ebay.com/staging/";
LoginPage loginPage = new LoginPage();
#Given("^I login to Ebay as \"([^\"]*)\"$")
public void iLoginToEbayAs(String username) throws Throwable {
Driver.Instance.navigate().to(Url);
loginPage.setUserName().sendKeys(username);
loginPage.setPassword().sendKeys("seeeev");
}
Receiving this error:
java.lang.NullPointerException
at Steps.MyStepdefs.iLoginToEbayAs(MyStepdefs.java:4)
MyStepdefs.java:4 == Driver.Instance.navigate().to(Url);
Help me pass through this!
Your Driver class never gets initialized, I'm betting Instance is null. I think you have at least 2 options, possibly more ways but this is what i'm thinking.
Instead of using #Before, which never gets executed because you don't have any test methods in that class, just make that a static "Init" method that you call in order to initialize your Instance variable
Make your Driver class an abstract class that your MyStepDefs class extends from. When you run your method iLoginToEbayAs() it will by default call the #Before method in the parent class and initialize your Instance variable as you expected.
Currently if you set a breakpoint in your #Before method I'm betting it's never getting executed hence NPE.
You are missing the argument in the step definition. it should be given below.
#Given("^I login to Ebay as \"([^\"]*)\"$")
public void iLoginToEbayAs(String role) throws Throwable {
Driver.Instance.navigate().to(Url);
}
have you imported the driver class?
realise this might be a bit of a big ask, but I'm having trouble splitting my test class to use the Page Object Model.
My current class basically works as so:
#BeforeClass - startUp() Loads properties file for variables and starts ChromeDriverService
#Before - createDriver() Opens Chrome browser, and navs to homepage
#Test - desktopHappyCallback() Does some page interaction, then calls:
hideDynamicElements() Hides some elements on the page
runScreenshotValidation() Saves a screenshot and compares it by calling:
compareScreen() Compares and returns a true/false
#After - tearDown() Quits the ChromeDriver
#AfterClass - stopService() Kills the ChromeDriverService
The class is currently (have cut bits out of the methods to make it shorter):
public class desktopHappy {
private static ChromeDriverService service;
private static WebDriver driver;
private static Properties obj = new Properties();
//Set up screenshot comparison via im4java
private static boolean compareScreen(String expectedImage, String currentImage, String diffImage) {
CompareCmd compare = new CompareCmd();
compare.setErrorConsumer(StandardStream.STDERR);
IMOperation comparisonExe = new IMOperation();
comparisonExe.metric("mae"); //mae = Mean Absolute error (average of all the color differences)
comparisonExe.addImage(currentImage);
}
//Compare via ImageMajick
private void runScreenshotValidation() throws IOException, InfoException {
String current = "screenshots\\current\\Current.png";
boolean compareSuccess = compareScreen(baseline, current, difference); //Run the compare method
}
}
//Hide dynamic elements on the page (if they exist)
private void hideDynamicElements() throws IOException, InterruptedException {
List<By> criteria = Arrays.asList(
By.className("telephone-number"),
By.cssSelector("#chatContainer"),
);
for (By dynamicElement : criteria) { //Loop through the criteria
List<WebElement> elements = driver.findElements(dynamicElement);
for (WebElement hideElement : elements){ //Loop through each instance of an element
((JavascriptExecutor) driver).executeScript("arguments[0].style.visibility='hidden'", hideElement);
}
}
#BeforeClass //Pulls in Properties, and starts up the ChromeDriverService before the Tests run
public static void startUp() throws IOException {
FileInputStream propfile = new FileInputStream(System.getProperty
("user.dir") + "\\src\\main\\resources\\config.properties");
obj.load(propfile);
service = new ChromeDriverService.Builder()
.usingDriverExecutable(new File(obj.getProperty("chromeDriverLoc"))) //Driver set in properties
.usingAnyFreePort()
.build();
service.start();
}
#Before //Starts up the Chrome browser (on home page) before each Test
public void createDriver() {
driver = new RemoteWebDriver(service.getUrl(), DesiredCapabilities.chrome());
driver.get(obj.getProperty("targetENV")); //Opens home page (set in properties)
}
#Test //Checks the Callback form (modal)
public void desktopHappyCallback() throws Exception {
driver.findElement(By.cssSelector("#callbackInputPhone")).sendKeys(obj.getProperty("formsPhone"));
driver.findElement(By.xpath("//input[#value='Request a callback']")).click();
WebDriverWait waitForSuccessMessage = new WebDriverWait(driver, 5);
waitForSuccessMessage.until(ExpectedConditions.elementToBeClickable
(By.cssSelector("#callbackForm > div.success-message")));
hideDynamicElements(); //Run the hide dynamic elements method
runScreenshotValidation(); //Run the screenshot comparison method
}
#After //Quits the ChromeDriver after each Test
public void tearDown() throws Exception {
driver.quit();
}
#AfterClass //Kills the ChromeDriverService at end of Tests
public static void stopService() {
service.stop();
}}
So in IntelliJ I've tried to split up my project with packages as so:
I've been trying to move into the baseCompare class:
hideDynamicElements()
compareScreen()
runScreenshotValidation()
Then into the baseSetup class:
startUp()
createDriver()
tearDown()
stopService()
Then homePage will contain my representations and desktopHappy will contain my test assertions.
However I'm getting really stuck working out how to split things up so that they work together. Is anyone able to give me an example on how I should be splitting things up under these packages? (sorry big ask!)
I think you are dividing your logic very fairly.
The only thing that i would change, is to have your base* classes under your base package, rather than an actual physical base package.
For example:
com.salessite/
baseCompare.java
baseSetup.java
basePage.java
baseTest.java
pages/
homePage.java < basePage.java
tests/
desktopHappy.java < baseTest.java
Also by creating more base's, you give yourself more leeway for future changes.
so that they work together
IF by work you mean, compile - then you should have no problem. say for example that homePage.java extends basePage.java, then in homePage.java, you'd have the appropriate import.
import com.salessite.basePage;
Importing is how to access external classes and references. (access modifiers permitting, of course.)