-3

I built a class to validate the submission of tweets to Twitter. Whenever I attempt to hit the submit button, I get an InvalidSelectorException. It seems to have a perfectly reasonable xpath, taking the form of xpath=(//button[@type='button'])[17], so I'm not sure what it's complaining about. Have a gander:

public class ValidationTest {
    private WebDriver driver;
    private String baseUrl;
    private StringBuffer verificationErrors = new StringBuffer();

    @Before
    public void setUp() throws Exception {

        // Google Chrome
        File file = new File("C:\\Users\\User\\plugins\\Twitter\\src\\chromedriver.exe");
        System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
        driver = new ChromeDriver();

        // Firefox
        // driver = new FirefoxDriver();

        baseUrl = "https://www.twitter.com";
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
    }

    @Test
    public void testValidation() throws Exception {

        // Authentication information
        String username = "user123";
        String password = "pass123";

        // Open site
        launchActivity("/");

        // Maximize window
        maximizeWindow();

        // Enter authentication information
        sendKeysAndWait("signin-email", username);
        sendKeysAndWait("signin-password", password);

        // Log in
        clickXPathButtonAndWait("//button[@type='submit']");

        // Parses a text file to produce an ArrayList from which short (140
        // char) messages may be sent
        parseStory();

    }

    /**
     * 
     * @param extension
     *            The remainder of the URL, after baseUrl
     */
    private void launchActivity(String extension) {
        driver.get(baseUrl + extension);
    }

    private void maximizeWindow() throws InterruptedException {
        driver.manage().window().maximize();
        sleepShort();
    }

    /**
     * s Writes a string to an HTML element and waits a random time
     * 
     * @param elem
     *            The element to send the keys
     * @param keys
     *            The string to write to the element
     * @throws InterruptedException
     */
    private void sendKeysAndWait(String elem, String keys) throws InterruptedException {
        driver.findElement(By.id(elem)).click();
        driver.findElement(By.id(elem)).sendKeys(keys);
        sleepShort();
    }

    /**
     * 
     * @param id
     *            The id of the button found in HTML
     * @throws InterruptedException
     */
    private void clickButtonAndWait(String id) throws InterruptedException {
        driver.findElement(By.id(id)).click();
        sleepShort();
    }

    @SuppressWarnings("unused")
    private void clickCSSButtonAndWait(String id) throws InterruptedException {
        driver.findElement(By.cssSelector(id)).click();
        sleepShort();
    }

    private void clickXPathButtonAndWait(String id) throws InterruptedException {
        driver.findElement(By.xpath(id)).click();
        sleepShort();
    }

    private void parseStory() throws FileNotFoundException, IOException, InterruptedException {
        FileInputStream fstream = new FileInputStream("C:\\Users\\User\\workspace\\Twitter\\src\\text.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
        String strLine;

        List<String> list = new ArrayList<String>();

        // Read the text file line by line
        while ((strLine = br.readLine()) != null) {

            // Create ArrayList to store text in 140 character chunks
            while ((strLine = br.readLine()) != null) {
                if (!strLine.isEmpty()) {
                    list.add(strLine);
                    String[] stringArr = strLine.split("(?<=\\G.{140})");
                    System.out.println(Arrays.toString(stringArr));

                    // Send 1.5 messages per minute (40 messages per hour) for a
                    // total of 960 per day
                    for (String s : stringArr) {
                        clickButtonAndWait("tweet-box-home-timeline");
                        sendKeysAndWait("tweet-box-home-timeline", s);

                        //TODO The result is not a node set. and therefore cannot be converted to the desired type.
                        clickXPathButtonAndWait("xpath=(//button[@type='button'])[17]");
                        sleepLong();
                    }

                    System.out.println("All messages have been sent.");
                }
            }
        }

        // Close the input stream
        br.close();
    }

    private void sleepLong() throws InterruptedException {
        int randomWaitDuration = 75000 + (int) (Math.random() * 105000);
        Thread.sleep(randomWaitDuration);
    }

    private void sleepShort() throws InterruptedException {
        int randomWaitDuration = 500 + (int) (Math.random() * 1000);
        Thread.sleep(randomWaitDuration);
    }

    @After
    public void tearDown() throws Exception {
        driver.quit();
        String verificationErrorString = verificationErrors.toString();
        if (!"".equals(verificationErrorString)) {
            fail(verificationErrorString);
        }
    }
}

Here is my stack trace:

org.openqa.selenium.InvalidSelectorException: invalid selector: Unable to locate an element with the xpath expression xpath=(//button[@type='button'])[17] because of the following error:
TypeError: Failed to execute 'evaluate' on 'Document': The result is not a node set, and therefore cannot be converted to the desired type.
  (Session info: chrome=51.0.2704.103)
  (Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 77 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/invalid_selector_exception.html
Build info: version: '2.53.0', revision: '35ae25b', time: '2016-03-15 16:57:40'
System info: host: 'OLCZPR112319', ip: '10.99.133.77', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_91'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={chromedriverVersion=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4), userDataDir=C:\Users\MNXE\AppData\Local\Temp\scoped_dir1332_417}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=51.0.2704.103, platform=XP, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: 8d72512617454899692b23a3f15ade99
*** Element info: {Using=xpath, value=xpath=(//button[@type='button'])[17]}
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:206)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:158)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:678)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:363)
    at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:500)
    at org.openqa.selenium.By$ByXPath.findElement(By.java:361)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:355)
    at ValidationTest.clickXPathButtonAndWait(ValidationTest.java:124)
    at ValidationTest.parseStory(ValidationTest.java:152)
    at ValidationTest.testValidation(ValidationTest.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Martin Erlic
  • 4,691
  • 10
  • 63
  • 123
  • `//button[@type='button']` is a perfectly reasonable `xpath`, but not `xpath=(//button[@type='button'])[17]` – Andersson Jul 13 '16 at 13:39
  • What have you tried and what was the result? Posting all of your code and saying take a look is strongly discouraged. Please read the help topics on how to ask a good question. You need to research your own issue, find code samples, etc. and write your own code to solve the issue. If you do all that and still can't figure it out, then come back and edit your question and add notes from the research you did, the code you have tried reduced to a [mcve], and what the result was... any error messages, etc. It's also very important to include any relevant HTML and properly format the HTML and code. – JeffC Jul 13 '16 at 13:53
  • Thanks. Sometimes it takes a fresh eye to see the obvious. – Martin Erlic Jul 13 '16 at 14:09

1 Answers1

1

This exception is occurred due to invalid xpath expression

"xpath=(//button[@type='button'])[17]"   

passed as argument to clickXPathButtonAndWait() method.

try this

 clickXPathButtonAndWait("//button[@type='button']")

as you used first time for log in .

Saurabh Gaur
  • 21,274
  • 8
  • 42
  • 69
Eknath
  • 529
  • 3
  • 11