HtmlUnitDriver is unable to locate a node - xpath

I cannot get HtmlUnitDriver to find elements on a page I am trying to access. WebDriver on the other hand works fine. Both are using the same method.
Here is my code:
import java.util.logging.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import com.gargoylesoftware.htmlunit.BrowserVersion;
public class Main {
public static void main(String[]args)
{
FirefoxDriver driver2=new FirefoxDriver();
HtmlUnitDriver driver=new HtmlUnitDriver(BrowserVersion.FIREFOX_10);
driver.setJavascriptEnabled(true);
Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
runTest(driver2); //works
runTest(driver); //does not work
}
public static void runTest(WebDriver driver)
{
driver.get("http://10.3.1.164");
WebElement elem=driver.findElement(By.xpath("//td[2]/input"));
assert elem.isDisplayed();
System.out.println(driver.getTitle());
}
}
Here is the stacktrace:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate a node using //td[2]/input
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '2.28.0', revision: '18309', time: '2012-12-11 20:21:45'
System info: os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_10'
Driver info: driver.version: HtmlUnitDriver
at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElementByXPath(HtmlUnitDriver.java:805)
at org.openqa.selenium.By$ByXPath.findElement(By.java:344)
at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1247)
at org.openqa.selenium.htmlunit.HtmlUnitDriver$5.call(HtmlUnitDriver.java:1)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.implicitlyWaitFor(HtmlUnitDriver.java:987)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:1244)
at org.openqa.selenium.htmlunit.HtmlUnitDriver.findElement(HtmlUnitDriver.java:393)
at Main.runTest(Main.java:28)
at Main.main(Main.java:22)

I figured it out. It was just a matter of me waiting for the elements to get loaded. Here's the code.
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.logging.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.htmlunit.*;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
public class Main {
public static void main(String[]args) throws FailingHttpStatusCodeException, MalformedURLException, IOException
{
FirefoxDriver driver2=new FirefoxDriver();
HtmlUnitDriver driver=new HtmlUnitDriver(BrowserVersion.FIREFOX_3_6);
driver.setJavascriptEnabled(true);
Logger.getLogger("com.gargoylesoftware").setLevel(Level.OFF);
runTest(driver2); //works
runTest(driver); //does not work
}
public static void runTest(WebDriver driver)
{
driver.get("http://10.3.1.164");
WebElement elem=(new WebDriverWait(driver, 10)) //added this line
.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//td[2]/input")));
System.out.println(elem.getAttribute("id"));
assert elem.isDisplayed();
System.out.println(driver.getTitle());
}
}

You just need to take care of timeOut. I just ran a simple HTMLUnitDriver test for today's lates availabel selenium-server-standalone.jar which is 3.8.1
Here is my java code:
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
public class HD_HTMLUnitTest {
public static void main(String[] args) throws InterruptedException {
// Creating a new instance of the HTML unit driver
//System.getProperties().put("http.proxyHost", "www-proxy.us.oracle.com");
//System.getProperties().put("http.proxyPort", "80");
HtmlUnitDriver unitDriver = new HtmlUnitDriver();
//unitDriver.setJavascriptEnabled(true);
unitDriver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
unitDriver.get("https://www.google.co.in");
System.out.println("Title of the page is -> " + unitDriver.getTitle());
unitDriver.findElement(By.name("q")).sendKeys("HTMLUnit through Selenium");
//searchBox.sendKeys("Selenium");
WebElement button = unitDriver.findElement(By.name("btnK"));
button.click();
System.out.println("Title of the page is -> " + unitDriver.getTitle());
unitDriver.quit();
}
}

Related

MockMvc ContentType is undefined in Result Action

I am working with Spring 2.7 & JUnit 5 on Eclipse and I have been trying to write a test statement for creating a product. Unfortunately, I am not sure what import statement I am missing (or not sure what is wrong with my statement.
I have these import statements currently:
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.List;
import java.util.Arrays;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.mock.web.MockHttpServletRequest;
These are the annotations I have on my test class:
#RunWith(SpringRunner.class)
#WebMvcTest
class RestControllerMvcTests {
and here is the specific test I have had an error with:
#Test
public void testCreateProduct() throws JsonProcessingException, Exception{
Product product = buildProduct(); //Function for a new product with test values
when(repo.save(any())).thenReturn(product);
ObjectWriter objwrite = new ObjectMapper().writer().withDefaultPrettyPrinter();
mockMvc.perform(get(PRODUCT_URL).contextPath(CONTEXT_URL))
.contentType(MediaType.APPLICATION_JSON) //the line that gives me an error
.content(objwrite.writeValueAsString(product))
.andExpect(status().isOk());
}
Overall, I tried importing different libraries without success and adding cast to the method. Adding cast instead created an error with .andExpect() so I would appreciate help on that if that is the solution I would use.
Be more careful with parentheses)
The contentType() and content() methods also refer to get().
#Test
public void testCreateProduct() throws JsonProcessingException, Exception{
Product product = buildProduct();
when(repo.save(any())).thenReturn(product);
ObjectWriter objwrite = new ObjectMapper().writer().withDefaultPrettyPrinter();
mockMvc.perform( get(PRODUCT_URL)
.contextPath(CONTEXT_URL)
.contentType(MediaType.APPLICATION_JSON)
.content(objwrite.writeValueAsString(product)) )
.andExpect(status().isOk());
}

Is it possible to use Qute templates in a custom extension?

I want to develop a Quarkus application that made of multiple independent components (custom extensions). Now, I need to each extension has own qute template; How can I do that?!
Here is a solution:
Put resources/templates/hello.html and this class in the deployment part of your custom extension.
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletionStage;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import io.quarkus.qute.Engine;
import io.quarkus.qute.Template;
import org.apache.commons.io.IOUtils;
#Path("hi")
public class TestQuteTemplateInDeployment {
public Template getTemplateFromFile(String path2template) {
Engine engine = Engine.builder().addDefaults().build();
ClassLoader classLoader = getClass().getClassLoader();
String content = "<!doctype html><html></html>";
try {
InputStream inputStream = classLoader.getResourceAsStream(path2template);
content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
} catch (Exception e) {
;
}
Template helloTemplate = engine.parse(content);
return helloTemplate;
}
#GET
#Produces(MediaType.TEXT_HTML)
public CompletionStage<String> get() {
return getTemplateFromFile("templates/hello.html").data("msg", "Hi! I'm Here.").renderAsync();
}
}

Running a quarkus main (command line like) from an AWS lambda handler method

I have a quarkus-camel batch application that needs to run under a lambda in AWS. This is working fine with pure java and spring-boot.
I need to be able to start the Quarkus Application from the AWS lambda handler method.
Running in batch works fine, but under lambda I get the following error:
Caused by: io.quarkus.bootstrap.BootstrapException: Failed to determine the Maven artifact associated with the application /var/task
This is the main java class. I need to know what to do in the handleRequest method to start the Quarkus (CAMEL) application.
package com.example;
import io.quarkus.runtime.annotations.QuarkusMain;
import io.quarkus.runtime.Quarkus;
import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.arc.Arc;
import io.quarkus.runtime.QuarkusApplication;
import org.apache.camel.quarkus.core.CamelRuntime;
import javax.inject.Inject;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
#QuarkusMain
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
public static void main(String... args) {
Quarkus.run(CamelApp.class, args);
}
public static class CamelApp implements QuarkusApplication {
#Inject
ProducerTemplate camelProducer;
#Inject
CamelContext camelContext;
#Override
public int run(String... args) throws Exception {
System.out.println("Hello Camel");
CamelRuntime runtime = Arc.container().instance(CamelRuntime.class).get();
runtime.start(args);
camelProducer.sendBody("direct:lambda", "how about this?");
return runtime.waitForExit();
}
}
public Object handleRequest(final Object input, final Context context) {
logger.info("input: {}", gson.toJson(input));
logger.info("context: {}", gson.toJson(context));
Quarkus.run(CamelApp.class);
// CamelRuntime runtime = Arc.container().instance(CamelRuntime.class).get();
// runtime.start(new String[] {"A","B","C"});
// camelProducer.sendBody("direct:lambda", "how about this?");
// runtime.waitForExit();
return input;
}
}

Asserting log messages using Mockito, TestNG and Log4j2

I've been following asserting-log-messages-with-log4j2-and-mockito to write TestNG test to test logging for Log4j2. Most of what is written in the post seems to work. However, when I'm running my test I'm getting:
Wanted but not invoked:
appender.append(<Capturing argument>);
-> at LoggingTest.test(LoggingTest.java:105)
However, there were exactly 2 interactions with this mock:
appender.getName();
-> at org.apache.logging.log4j.core.config.AbstractConfiguration.addAppender(AbstractConfiguration.java:603)
appender.getName();
-> at org.apache.logging.log4j.core.config.AppenderControl.<init>(AppenderControl.java:51)
My TestNGclass is:
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.mockito.ArgumentCaptor;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class LoggingTest {
private Appender appender;
private ArgumentCaptor<LogEvent> captor;
#BeforeMethod
public void setUp() {
appender = mock(Appender.class);
captor = ArgumentCaptor.forClass(LogEvent.class);
reset(appender);
when(appender.getName()).thenReturn("Appender");
when(appender.isStarted()).thenReturn(true);
when(appender.isStopped()).thenReturn(false);
LoggerContext context = (LoggerContext)LogManager.getContext();
Configuration config = context.getConfiguration();
config.addAppender(appender);
LoggerConfig rootConfig = config.getRootLogger();
rootConfig.setLevel(Level.INFO);
rootConfig.addAppender(appender, Level.INFO, null);
context.updateLoggers();
}
#Test
public void test() {
LogManager.getLogger().info("testing");
verify(appender).append(captor.capture());
LogEvent logEvent = captor.getValue();
assertThat(logEvent.getMessage()).isEqualTo("test");
}
}
I've been looking at this for a while and have not been able to find a my error. Could someone point me in the right direction?

Getting Geckodriver error evenif it is defined in code

I am using 2 classes for my basic Maven and Selenium project-openGmail. I am using Selenium 3.5 with Firefox 47.0.1 and Gecodriver 0.18.
My Main class is:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class MainClass {
WebDriver driver = new FirefoxDriver();
public void setup() {
String Path_GecoDriver="C:/Personal/Selenium/setup/geckodriver-v0.18.0-win64";
System.setProperty("webdriver.firefox.marionette", Path_GecoDriver+"/geckodriver.exe");
System.setProperty("webdriver.gecko.driver", Path_GecoDriver+"/geckodriver.exe");
}
public void OpenBrowser() {
String url="http://google.co.in";
driver.get(url);
}
public void LoginGmail() throws InterruptedException {
String username ="username";
String passwd = "passwd";
driver.findElement(By.linkText("Gmail")).click();
driver.findElement(By.id("identifierId")).sendKeys(username);
WebElement cli=driver.findElement(By.xpath("//*[text()='Next']"));
cli.click();
Thread.sleep(1000);
driver.findElement(By.xpath("//input[#name='password']")).sendKeys(passwd);
driver.findElement(By.xpath("//*[text()='Next']")).click();
}
public void CloseBrowser() {
driver.close();
}
}
My other class is:-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class TestngClass {
MainClass mc=new MainClass();
#Before
public void sp() {
mc.setup();
mc.OpenBrowser();
}
#Test
public void LG() throws InterruptedException {
mc.LoginGmail();
}
#After
public void CB() {
mc.CloseBrowser();
}
}
I am getting the error
java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information
I have tried to execute it the test by putting my System.setProperty (prop, path/to/driver) in my #Before, and # test also but no change, I am still getting the error.
If I use a single class then everything works fine so I think I am placing my system.setProperty at the wrong place.
I have started with Java and Selenium very recently. I have even tried to put my Gecko driver exe in src/main/resources of my Maven project as mentioned in In System.setProperty("webdriver.gecko.driver", "<Path to your WebDriver>"), what is meant by "Path to your WebDriver"?
You have set the property two times as below :-
System.setProperty("webdriver.firefox.marionette", Path_GecoDriver+"/geckodriver.exe");
System.setProperty("webdriver.gecko.driver", Path_GecoDriver+"/geckodriver.exe");
Remove :-
System.setProperty("webdriver.firefox.marionette", Path_GecoDriver+"/geckodriver.exe");
Another thing is you have to set it before creating the firefox instance. You have define the instance first and then you are setting up the preference .
Try something like below :-
WebDriver driver =null;
public void setup() {
String Path_GecoDriver="C:/Personal/Selenium/setup/geckodriver-v0.18.0-win64";
System.setProperty("webdriver.gecko.driver", Path_GecoDriver+"/geckodriver.exe");
driver= new FirefoxDriver();
}
Hope it will help you :)

Resources