/* * Copyright (c) 2002-2008 Gargoyle Software Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gargoylesoftware.htmlunit.html.xpath; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; import com.gargoylesoftware.htmlunit.BrowserVersion; import com.gargoylesoftware.htmlunit.WebTestCase; import com.gargoylesoftware.htmlunit.html.DomNode; import com.gargoylesoftware.htmlunit.html.DomText; import com.gargoylesoftware.htmlunit.html.HtmlBody; import com.gargoylesoftware.htmlunit.html.HtmlElement; import com.gargoylesoftware.htmlunit.html.HtmlPage; /** * Tests for XPath evaluation on HtmlUnit DOM. * * @version $Revision$ * @author Marc Guillemot * @author Ahmed Ashour */ public class HtmlUnitXPathTest extends WebTestCase { /** * Test evaluation of some simple paths. * @throws Exception if test fails */ @Test public void simplePath() throws Exception { final String content = "Test page\n" + "foo\n" + ""; final HtmlPage page = loadPage(content); assertEquals(page.getDocumentElement(), page.getFirstByXPath("/html")); assertEquals(page.getDocumentElement().getFirstChild(), page.getFirstByXPath("/html/head")); assertEquals(page.getHtmlElementById("myLink"), page.getFirstByXPath("/html/body/a")); assertEquals("Test page", ((DomText) page.getFirstByXPath("/html/head/title/text()")).getNodeValue()); } /** * Test evaluation relative from elements other than the whole page. * @throws Exception if test fails */ @Test public void xpathFromElement() throws Exception { final String content = "Test page\n" + "foo\n" + ""; final HtmlPage page = loadPage(content); final HtmlBody body = (HtmlBody) page.getFirstByXPath("/html/body"); assertEquals(page.getHtmlElementById("myLink"), body.getFirstByXPath("./a")); } /** * Test that the elements are in the right order. * @throws Exception if test fails */ @Test @SuppressWarnings("unchecked") public void elementOrder() throws Exception { final String content = "First\n" + ""; final HtmlPage page = loadPage(content); final List< ? > list = page.getByXPath("//*"); final String[] expected = {"html", "head", "title", "script", "body"}; final List actualNames = new ArrayList(); for (final DomNode node : (List) list) { actualNames.add(node.getNodeName()); } assertEquals(expected, actualNames); } /** * Test evaluation of paths after they're changed through JavaScript. * @throws Exception if test fails */ @Test public void whenJSChangesPage() throws Exception { final String content = "foo\n" + "\n" + "\n" + "

hello world

\n" + "
\n" + " \n" + "
\n" + "add option\n" + ""; final HtmlPage page = loadPage(content); assertEquals("foo", page.getTitleText()); assertEquals(3, ((Double) page.getFirstByXPath("count(//select[@name='select1']/option)")).intValue()); page.getAnchors().get(0).click(); assertEquals(4, ((Double) page.getFirstByXPath("count(//select[@name='select1']/option)")).intValue()); } /** * Tests XPath where results are attributes. * @throws Exception if test fails */ @Test @SuppressWarnings("unchecked") public void listAttributesResult() throws Exception { final String content = "\n" + "\n" + "\n" + "\n" + ""; final HtmlPage page = loadPage(content); final List< ? > nameList = page.getByXPath("//img/@src"); final List< ? > valueList = new ArrayList(nameList); final String[] expectedNames = {"src", "src", "src"}; final List collectedNames = new ArrayList(); for (final DomNode node : (List) nameList) { collectedNames.add(node.getNodeName()); } assertEquals(expectedNames, collectedNames); final String[] expectedValues = {"1.png", "2.png", "3.png"}; final List collectedValues = new ArrayList(); for (final DomNode node : (List) valueList) { collectedValues.add(node.getNodeValue()); } assertEquals(expectedValues, collectedValues); } /** * @throws Exception if the test fails */ @Test public void optionText() throws Exception { final String content = "foo\n" + " \n" + ""; final String[] expectedAlerts = {"102", "111", "111", "160", "97", "110", "100", "160", "102", "111", "111"}; final List collectedAlerts = new ArrayList(); loadPage(BrowserVersion.FIREFOX_2, content, collectedAlerts); assertEquals(expectedAlerts, collectedAlerts); } /** * Test if option/text() is cleaned like other text(). * @throws Exception if test fails */ @Test public void optionText_getFirstByXPath() throws Exception { final String content = "Test page\n" + "
\n" + "\n" + "
"; final HtmlPage page = loadPage(content); final String value = (String) page.getFirstByXPath("string(//option)"); final int[] expectedValues = {102, 111, 111, 160, 97, 110, 100, 160, 102, 111, 111}; int index = 0; for (final int v : expectedValues) { if (value.codePointAt(index++) != v) { fail(); } } } /** * Regression test for https://sf.net/tracker/index.php?func=detail&aid=1527799&group_id=47038&atid=448266. * @throws Exception if test fails */ @Test public void followingAxis() throws Exception { final String content = "XPath tests\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "
a3c
a4c
\n" + ""; final HtmlPage page = loadPage(content); final HtmlElement td12 = page.getHtmlElementById("td12"); final HtmlElement tr2 = page.getHtmlElementById("tr2"); final HtmlElement td21 = page.getHtmlElementById("td21"); final HtmlElement td22 = page.getHtmlElementById("td22"); xpath(page, "//*[contains(.,'a4')]/following::td[.='c']", new Object[] {td22}); xpath(page, "//body/following::*", new Object[] {}); xpath(page, "//html/following::*", new Object[] {}); xpath(page, "//table/following::*", new Object[] {}); xpath(page, "//td[@id='td11']/following::*", new Object[] {td12, tr2, td21, td22}); } private void xpath(final HtmlPage page, final String xpathExpr, final Object[] expectedNodes) throws Exception { assertEquals(Arrays.asList(expectedNodes), page.getByXPath(xpathExpr)); } /** * @throws Exception if test fails */ @Test public void id() throws Exception { final String content = "foo\n" + "\n" + "
\n" + ""; final HtmlPage page = loadPage(content); assertNull(page.getFirstByXPath("//div[@id='doesNotExist']")); assertNull(page.getFirstByXPath("id('doesNotExist')")); } }