/* * JBoss, Home of Professional Open Source * Copyright 2013, Red Hat, Inc. and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.richfaces.component.chart; import static org.jboss.arquillian.graphene.Graphene.waitAjax; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import java.net.URL; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.graphene.javascript.JavaScript; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.FindBy; import org.richfaces.integration.RichDeployment; import org.richfaces.shrinkwrap.descriptor.FaceletAsset; import category.Smoke; @RunWith(Arquillian.class) public class ITChartBasic { @Drone WebDriver browser; @ArquillianResource URL deploymentUrl; @JavaScript ChartJs chtestjs; @FindBy(xpath = "//div[@id='frm:chartChart']/canvas[@class='flot-overlay']") WebElement chartCanvas; @FindBy(id = "clickInfo") WebElement clickInfo; @FindBy(id = "hoverInfo") WebElement hoverInfo; @FindBy(id = "frm:msg") WebElement serverSideInfo; @Deployment(testable = false) public static WebArchive createDeployment() { RichDeployment deployment = new RichDeployment(ITChartBasic.class); deployment.archive().addClasses(ChartBean.class); addIndexPage(deployment); return deployment.getFinalArchive(); } private static void addIndexPage(RichDeployment deployment) { FaceletAsset p = new FaceletAsset(); p.head("<style type='text/css'>"); p.head(".richfaces-chart {"); p.head("width: 600px;"); p.head("height: 400px;"); p.head("}"); p.head("</style>"); p.head(" <script type='text/javascript'>"); p.head("//<![CDATA["); p.head("function logClick(event){"); p.head(" $('#clickInfo').text(event.data.x+','+event.data.y);"); p.head("}"); p.head("function hover(e){"); p.head(" $('#hoverInfo').text(e.data.item.series.label+' ['+e.data.x+','+e.data.y+']');"); p.head("}"); p.head("function clear(){"); p.head(" $('#hoverInfo').text('');"); p.head("}"); p.head("//]]>"); p.head("</script>"); p.body("<h:form id='frm'>"); p.body("<rich:chart id='chart' zoom ='true' title='ChartTitle' onplotclick='logClick(event)' onplothover='hover(event)' onmouseout='clear()' plotClickListener='#{chartBean.handler}' >"); p.body(" <a4j:repeat value='#{chartBean.countries}' var='country'>"); p.body(" <rich:chartSeries label='#{country.name}' type='line'>"); p.body(" <a4j:repeat value='#{country.data}' var='record'>"); p.body(" <rich:chartPoint x='#{record.year}' y='#{record.tons}' />"); p.body(" </a4j:repeat>"); p.body(" </rich:chartSeries>"); p.body(" </a4j:repeat>"); p.body(" <a4j:ajax event='plotclick' render='msg' execute='msg' />"); p.body(" <rich:chartXAxis label='year' />"); p.body(" <rich:chartYAxis label='metric tons of CO2 per capita' />"); p.body("</rich:chart>"); p.body("<h:outputText id='msg' value='#{chartBean.msg}' />"); p.body("</h:form>"); p.body("<span id='clickInfo'></span>"); p.body("<br />"); p.body("<span id='hoverInfo'></span>"); deployment.archive().addAsWebResource(p, "index.xhtml"); } @Test @Category(Smoke.class) public void testChartRendered() { browser.get(deploymentUrl.toExternalForm()); // asserts that the chart, canvas and title were rendered assertNotNull("Chart should be present.", browser.findElement(By.id("frm:chartChart"))); assertNotNull("Canvas should be created.", browser.findElement(By.xpath("//div[@id='frm:chartChart']/canvas[@class='flot-base']"))); assertEquals("ChartTitle", browser.findElement(By.xpath("//div[@id='frm:chart']/div[@class='chart-title']")).getText()); } @Test public void testChartEvents() { // does not work on FF - Webdriver cannot click into position on canvas hence cannot fire event final String serverSide = "Server's speaking:Point with index 0 within series 0 was clicked. Point coordinates: [1990,19.1]."; final String plotClick = "1990,19.1"; final String plotHover = "USA [1990,19.1]"; browser.get(deploymentUrl.toExternalForm()); // retrieve plot offset in canvas via JS (coordinates differ based on browser) int x = chtestjs.pointXPos("frm:chart", 0, 0); int y = chtestjs.pointYPos("frm:chart", 0, 0); // onplotclick client side new Actions(browser).moveToElement(chartCanvas, x, y).click().build().perform(); waitAjax(browser).until().element(clickInfo).text().contains(plotClick); // onplotclick server side, since the element was already clicked only assertion is needed waitAjax(browser).until().element(serverSideInfo).text().contains(serverSide); // onplothover, first move away to clear the text from previous events new Actions(browser).moveToElement(serverSideInfo).click().build().perform(); new Actions(browser).moveToElement(chartCanvas, x, y).build().perform(); waitAjax(browser).until().element(hoverInfo).text().contains(plotHover); } @Test public void testZoom() { // does not work on FF - Webdriver cannot click into position on canvas browser.get(deploymentUrl.toExternalForm()); // get plot coordinates on screen before zooming int xBeforeZoom = chtestjs.pointXPos("frm:chart", 0, 0); // zoom some area new Actions(browser) .moveToElement(chartCanvas, chtestjs.pointXPos("frm:chart", 1, 1), chtestjs.pointYPos("frm:chart", 1, 1)) .clickAndHold() .moveToElement(chartCanvas, chtestjs.pointXPos("frm:chart", 2, 2), chtestjs.pointYPos("frm:chart", 2, 2)).release() .build().perform(); // new Actions(browser).clickAndHold().moveByOffset(200, 50).release().build().perform(); // get the coordinates after zooming, they should be different int xAfterZoom = chtestjs.pointXPos("frm:chart", 0, 0); // assert coordinates do not equal after zoom, only x axis is zoomed assertNotEquals(xBeforeZoom, xAfterZoom); // perform zoom reset by JS chtestjs.resetZoom("frm:chart"); // get the coordinates again int xZoomReset = chtestjs.pointXPos("frm:chart", 0, 0); // assert that this equals initial state, only x axis is zoomed assertEquals(xBeforeZoom, xZoomReset); } }