You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractTB3Test.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /*
  2. * Copyright 2000-2013 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.tests.tb3;
  17. import java.net.URL;
  18. import java.util.Collection;
  19. import java.util.Collections;
  20. import java.util.logging.Logger;
  21. import org.junit.After;
  22. import org.junit.Before;
  23. import org.junit.runner.RunWith;
  24. import org.openqa.selenium.By;
  25. import org.openqa.selenium.Platform;
  26. import org.openqa.selenium.WebDriver;
  27. import org.openqa.selenium.WebElement;
  28. import org.openqa.selenium.remote.BrowserType;
  29. import org.openqa.selenium.remote.DesiredCapabilities;
  30. import org.openqa.selenium.remote.RemoteWebDriver;
  31. import org.openqa.selenium.support.ui.ExpectedCondition;
  32. import org.openqa.selenium.support.ui.ExpectedConditions;
  33. import org.openqa.selenium.support.ui.WebDriverWait;
  34. import com.vaadin.server.LegacyApplication;
  35. import com.vaadin.server.UIProvider;
  36. import com.vaadin.testbench.TestBench;
  37. import com.vaadin.testbench.TestBenchTestCase;
  38. import com.vaadin.tests.components.AbstractTestUIWithLog;
  39. import com.vaadin.ui.UI;
  40. /**
  41. * Base class for TestBench 3+ tests. All TB3+ tests in the project should
  42. * extend this class.
  43. *
  44. * Provides:
  45. * <ul>
  46. * <li>Helpers for browser selection</li>
  47. * <li>Hub connection setup and teardown</li>
  48. * <li>Automatic generation of URL for a given test on the development server
  49. * using {@link #getUIClass()} or by automatically finding an enclosing UI class
  50. * and based on requested features, e.g. {@link #isDebug()}, {@link #isPush()}</li>
  51. * <li>Generic helpers for creating TB3+ tests</li>
  52. * </ul>
  53. *
  54. * @author Vaadin Ltd
  55. */
  56. @RunWith(value = TB3Runner.class)
  57. public abstract class AbstractTB3Test extends TestBenchTestCase {
  58. /**
  59. * Height of the screenshots we want to capture
  60. */
  61. private static final int SCREENSHOT_HEIGHT = 850;
  62. /**
  63. * Width of the screenshots we want to capture
  64. */
  65. private static final int SCREENSHOT_WIDTH = 1500;
  66. private DesiredCapabilities desiredCapabilities;
  67. private boolean debug = false;
  68. private boolean push = false;
  69. {
  70. // Default browser to run on unless setDesiredCapabilities is called
  71. desiredCapabilities = BrowserUtil
  72. .firefox(MultiBrowserTest.TESTED_FIREFOX_VERSION);
  73. }
  74. /**
  75. * Connect to the hub using a remote web driver, set the canvas size and
  76. * opens the initial URL as specified by {@link #getTestUrl()}
  77. *
  78. * @throws Exception
  79. */
  80. @Before
  81. public void setup() throws Exception {
  82. setupDriver();
  83. }
  84. /**
  85. * Creates and configure the web driver to be used for the test. By default
  86. * creates a remote web driver which connects to {@link #getHubURL()} and
  87. * selects a browser based on {@link #getDesiredCapabilities()}.
  88. *
  89. * This method MUST call {@link #setDriver(WebDriver)} with the newly
  90. * generated driver.
  91. *
  92. * @throws Exception
  93. * If something goes wrong
  94. */
  95. protected void setupDriver() throws Exception {
  96. if (runLocally()) {
  97. setupLocalDriver();
  98. return;
  99. }
  100. DesiredCapabilities capabilities = getDesiredCapabilities();
  101. WebDriver dr = TestBench.createDriver(new RemoteWebDriver(new URL(
  102. getHubURL()), capabilities));
  103. setDriver(dr);
  104. int w = SCREENSHOT_WIDTH;
  105. int h = SCREENSHOT_HEIGHT;
  106. if (BrowserUtil.isIE8(capabilities)) {
  107. // IE8 gets size wrong, who would have guessed...
  108. w += 4;
  109. h += 4;
  110. }
  111. try {
  112. testBench().resizeViewPortTo(w, h);
  113. } catch (UnsupportedOperationException e) {
  114. // Opera does not support this...
  115. }
  116. }
  117. /**
  118. * Override and return true to run the test locally. This method is only to
  119. * be used for developing tests.
  120. *
  121. * @return true to run the test on a local browser, false to use the hub
  122. */
  123. public boolean runLocally() {
  124. return false;
  125. }
  126. /**
  127. * Creates a {@link WebDriver} instance used for running the test locally
  128. * for debug purposes. Used only when {@link #runLocally()} is overridden to
  129. * return true;
  130. */
  131. protected abstract void setupLocalDriver();
  132. /**
  133. * Opens the given test (defined by {@link #getTestUrl(boolean, boolean)},
  134. * optionally with debug window and/or push
  135. *
  136. * @param debug
  137. * @param push
  138. */
  139. protected void openTestURL() {
  140. driver.get(getTestUrl());
  141. }
  142. /**
  143. * Returns the full URL to be used for the test
  144. *
  145. * @return the full URL for the test
  146. */
  147. protected String getTestUrl() {
  148. String baseUrl = getBaseURL();
  149. if (baseUrl.endsWith("/")) {
  150. baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
  151. }
  152. return baseUrl + getDeploymentPath();
  153. }
  154. /**
  155. *
  156. * @return the location (URL) of the TB hub
  157. */
  158. protected String getHubURL() {
  159. return "http://" + getHubHostname() + ":4444/wd/hub";
  160. }
  161. /**
  162. * Used for building the hub URL to use for the test
  163. *
  164. * @return the host name of the TestBench hub
  165. */
  166. protected abstract String getHubHostname();
  167. /**
  168. * Used to determine what URL to initially open for the test
  169. *
  170. * @return the host name of development server
  171. */
  172. protected abstract String getDeploymentHostname();
  173. /**
  174. * Used to determine what port the test is running on
  175. *
  176. * @return The port teh test is running on, by default 8888
  177. */
  178. protected abstract String getDeploymentPort();
  179. /**
  180. * Produces a collection of browsers to run the test on. This method is
  181. * executed by the test runner when determining how many test methods to
  182. * invoke and with what parameters. For each returned value a test method is
  183. * ran and before running that,
  184. * {@link #setDesiredCapabilities(DesiredCapabilities)} is invoked with the
  185. * value returned by this method.
  186. *
  187. * This method is not static to allow overriding it in sub classes. By
  188. * default runs the test only on Firefox
  189. *
  190. * @return The browsers to run the test on
  191. */
  192. public Collection<DesiredCapabilities> getBrowsersToTest() {
  193. return Collections.singleton(BrowserUtil
  194. .firefox(MultiBrowserTest.TESTED_FIREFOX_VERSION));
  195. }
  196. /**
  197. * Used to determine which capabilities should be used when setting up a
  198. * {@link WebDriver} for this test. Typically set by a test runner or left
  199. * at its default (Firefox 24). If you want to run a test on a single
  200. * browser other than Firefox 24 you can override this method.
  201. *
  202. * @return the requested browser capabilities
  203. */
  204. protected DesiredCapabilities getDesiredCapabilities() {
  205. return desiredCapabilities;
  206. }
  207. /**
  208. * Sets the requested browser capabilities (typically browser name and
  209. * version)
  210. *
  211. * @param desiredCapabilities
  212. */
  213. public void setDesiredCapabilities(DesiredCapabilities desiredCapabilities) {
  214. this.desiredCapabilities = desiredCapabilities;
  215. }
  216. /**
  217. * Shuts down the driver after the test has been completed
  218. *
  219. * @throws Exception
  220. */
  221. @After
  222. public void tearDown() throws Exception {
  223. if (driver != null) {
  224. driver.quit();
  225. }
  226. driver = null;
  227. }
  228. /**
  229. * Finds an element based on the part of a TB2 style locator following the
  230. * :: (e.g. vaadin=runLabelModes::PID_Scheckboxaction-Enabled/domChild[0] ->
  231. * PID_Scheckboxaction-Enabled/domChild[0]).
  232. *
  233. * @param vaadinLocator
  234. * The part following :: of the vaadin locator string
  235. * @return
  236. */
  237. protected WebElement vaadinElement(String vaadinLocator) {
  238. return driver.findElement(vaadinLocator(vaadinLocator));
  239. }
  240. /**
  241. * Find a Vaadin element based on its id given using Component.setId
  242. *
  243. * @param id
  244. * The id to locate
  245. * @return
  246. */
  247. public WebElement vaadinElementById(String id) {
  248. return driver.findElement(vaadinLocatorById(id));
  249. }
  250. /**
  251. * Finds a {@link By} locator based on the part of a TB2 style locator
  252. * following the :: (e.g.
  253. * vaadin=runLabelModes::PID_Scheckboxaction-Enabled/domChild[0] ->
  254. * PID_Scheckboxaction-Enabled/domChild[0]).
  255. *
  256. * @param vaadinLocator
  257. * The part following :: of the vaadin locator string
  258. * @return
  259. */
  260. public org.openqa.selenium.By vaadinLocator(String vaadinLocator) {
  261. String base = getApplicationId(getDeploymentPath());
  262. base += "::";
  263. return com.vaadin.testbench.By.vaadin(base + vaadinLocator);
  264. }
  265. /**
  266. * Constructs a {@link By} locator for the id given using Component.setId
  267. *
  268. * @param id
  269. * The id to locate
  270. * @return a locator for the given id
  271. */
  272. public By vaadinLocatorById(String id) {
  273. return vaadinLocator("PID_S" + id);
  274. }
  275. /**
  276. * Waits a short while for the given condition to become true. Use e.g. as
  277. * {@link #waitUntil(ExpectedConditions.textToBePresentInElement(by, text))}
  278. *
  279. * @param condition
  280. * the condition to wait for to become true
  281. */
  282. protected void waitUntil(ExpectedCondition<Boolean> condition) {
  283. new WebDriverWait(driver, 10).until(condition);
  284. }
  285. /**
  286. * Waits a short while for the given condition to become false. Use e.g. as
  287. * {@link #waitUntilNot(ExpectedConditions.textToBePresentInElement(by,
  288. * text))}
  289. *
  290. * @param condition
  291. * the condition to wait for to become false
  292. */
  293. protected void waitUntilNot(ExpectedCondition<Boolean> condition) {
  294. new WebDriverWait(driver, 10).until(ExpectedConditions.not(condition));
  295. }
  296. /**
  297. * For tests extending {@link AbstractTestUIWithLog}, returns the element
  298. * for the Nth log row
  299. *
  300. * @param rowNr
  301. * The log row to retrieve
  302. * @return the Nth log row
  303. */
  304. protected WebElement getLogRowElement(int rowNr) {
  305. return vaadinElementById("Log_row_" + rowNr);
  306. }
  307. /**
  308. * For tests extending {@link AbstractTestUIWithLog}, returns the text in
  309. * the Nth log row
  310. *
  311. * @param rowNr
  312. * The log row to retrieve text for
  313. * @return the text in the log row
  314. */
  315. protected String getLogRow(int rowNr) {
  316. return getLogRowElement(rowNr).getText();
  317. }
  318. /**
  319. * Asserts that {@literal a} is &gt;= {@literal b}
  320. *
  321. * @param message
  322. * The message to include in the {@link AssertionError}
  323. * @param a
  324. * @param b
  325. * @throws AssertionError
  326. * If comparison fails
  327. */
  328. public static final <T> void assertGreaterOrEqual(String message,
  329. Comparable<T> a, T b) throws AssertionError {
  330. if (a.compareTo(b) >= 0) {
  331. return;
  332. }
  333. throw new AssertionError(decorate(message, a, b));
  334. }
  335. /**
  336. * Asserts that {@literal a} is &gt; {@literal b}
  337. *
  338. * @param message
  339. * The message to include in the {@link AssertionError}
  340. * @param a
  341. * @param b
  342. * @throws AssertionError
  343. * If comparison fails
  344. */
  345. public static final <T> void assertGreater(String message, Comparable<T> a,
  346. T b) throws AssertionError {
  347. if (a.compareTo(b) > 0) {
  348. return;
  349. }
  350. throw new AssertionError(decorate(message, a, b));
  351. }
  352. /**
  353. * Asserts that {@literal a} is &lt;= {@literal b}
  354. *
  355. * @param message
  356. * The message to include in the {@link AssertionError}
  357. * @param a
  358. * @param b
  359. * @throws AssertionError
  360. * If comparison fails
  361. */
  362. public static final <T> void assertLessThanOrEqual(String message,
  363. Comparable<T> a, T b) throws AssertionError {
  364. if (a.compareTo(b) <= 0) {
  365. return;
  366. }
  367. throw new AssertionError(decorate(message, a, b));
  368. }
  369. /**
  370. * Asserts that {@literal a} is &lt; {@literal b}
  371. *
  372. * @param message
  373. * The message to include in the {@link AssertionError}
  374. * @param a
  375. * @param b
  376. * @throws AssertionError
  377. * If comparison fails
  378. */
  379. public static final <T> void assertLessThan(String message,
  380. Comparable<T> a, T b) throws AssertionError {
  381. if (a.compareTo(b) < 0) {
  382. return;
  383. }
  384. throw new AssertionError(decorate(message, a, b));
  385. }
  386. private static <T> String decorate(String message, Comparable<T> a, T b) {
  387. message = message.replace("{0}", a.toString());
  388. message = message.replace("{1}", b.toString());
  389. return message;
  390. }
  391. /**
  392. * Returns the path that should be used for the test. The path contains the
  393. * full path (appended to hostname+port) and must start with a slash.
  394. *
  395. * @param push
  396. * true if "?debug" should be added
  397. * @param debug
  398. * true if /run-push should be used instead of /run
  399. *
  400. * @return The URL path to the UI class to test
  401. */
  402. protected String getDeploymentPath() {
  403. Class<?> uiClass = getUIClass();
  404. if (uiClass != null) {
  405. return getDeploymentPath(uiClass);
  406. }
  407. throw new IllegalArgumentException("Unable to determine path for "
  408. + getClass().getCanonicalName());
  409. }
  410. /**
  411. * Returns the UI class the current test is connected to (or in special
  412. * cases UIProvider or LegacyApplication). Uses the enclosing class if the
  413. * test class is a static inner class to a UI class.
  414. *
  415. * Test which are not enclosed by a UI class must implement this method and
  416. * return the UI class they want to test.
  417. *
  418. * Note that this method will update the test name to the enclosing class to
  419. * be compatible with TB2 screenshot naming
  420. *
  421. * @return the UI class the current test is connected to
  422. */
  423. protected Class<?> getUIClass() {
  424. try {
  425. // Convention: SomeUITest uses the SomeUI UI class
  426. String uiClassName = getClass().getName().replaceFirst("Test$", "");
  427. Class<?> cls = Class.forName(uiClassName);
  428. if (isSupportedRunnerClass(cls)) {
  429. return cls;
  430. }
  431. } catch (Exception e) {
  432. }
  433. Class<?> enclosingClass = getClass().getEnclosingClass();
  434. if (enclosingClass != null) {
  435. if (UI.class.isAssignableFrom(enclosingClass)) {
  436. Logger.getLogger(getClass().getName())
  437. .severe("Test is an static inner class to the UI. This will no longer be supported in the future. The test should be named UIClassTest and reside in the same package as the UI");
  438. return enclosingClass;
  439. }
  440. }
  441. throw new RuntimeException(
  442. "Could not determine UI class. Ensure the test is named UIClassTest and is in the same package as the UIClass");
  443. }
  444. /**
  445. * @return true if the given class is supported by ApplicationServletRunner
  446. */
  447. @SuppressWarnings("deprecation")
  448. private boolean isSupportedRunnerClass(Class<?> cls) {
  449. if (UI.class.isAssignableFrom(cls)) {
  450. return true;
  451. }
  452. if (UIProvider.class.isAssignableFrom(cls)) {
  453. return true;
  454. }
  455. if (LegacyApplication.class.isAssignableFrom(cls)) {
  456. return true;
  457. }
  458. return false;
  459. }
  460. /**
  461. * Returns whether to run the test in debug mode (with the debug console
  462. * open) or not
  463. *
  464. * @return true to run with the debug window open, false by default
  465. */
  466. protected final boolean isDebug() {
  467. return debug;
  468. }
  469. /**
  470. * Sets whether to run the test in debug mode (with the debug console open)
  471. * or not.
  472. *
  473. * @param debug
  474. * true to open debug window, false otherwise
  475. */
  476. protected final void setDebug(boolean debug) {
  477. this.debug = debug;
  478. }
  479. /**
  480. * Returns whether to run the test with push enabled (using /run-push) or
  481. * not. Note that push tests can and should typically be created using @Push
  482. * on the UI instead of overriding this method
  483. *
  484. * @return true if /run-push is used, false otherwise
  485. */
  486. protected final boolean isPush() {
  487. return push;
  488. }
  489. /**
  490. * Sets whether to run the test with push enabled (using /run-push) or not.
  491. * Note that push tests can and should typically be created using @Push on
  492. * the UI instead of overriding this method
  493. *
  494. * @param push
  495. * true to use /run-push in the test, false otherwise
  496. */
  497. protected final void setPush(boolean push) {
  498. this.push = push;
  499. }
  500. /**
  501. * Returns the path for the given UI class when deployed on the test server.
  502. * The path contains the full path (appended to hostname+port) and must
  503. * start with a slash.
  504. *
  505. * This method takes into account {@link #isPush()} and {@link #isDebug()}
  506. * when the path is generated.
  507. *
  508. * @param uiClass
  509. * @param push
  510. * true if "?debug" should be added
  511. * @param debug
  512. * true if /run-push should be used instead of /run
  513. * @return The path to the given UI class
  514. */
  515. private String getDeploymentPath(Class<?> uiClass) {
  516. String runPath = "/run";
  517. if (isPush()) {
  518. runPath = "/run-push";
  519. }
  520. if (UI.class.isAssignableFrom(uiClass)) {
  521. return runPath + "/" + uiClass.getCanonicalName()
  522. + (isDebug() ? "?debug" : "");
  523. } else if (LegacyApplication.class.isAssignableFrom(uiClass)) {
  524. return runPath + "/" + uiClass.getCanonicalName()
  525. + "?restartApplication" + (isDebug() ? "&debug" : "");
  526. } else {
  527. throw new IllegalArgumentException(
  528. "Unable to determine path for enclosing class "
  529. + uiClass.getCanonicalName());
  530. }
  531. }
  532. /**
  533. * Used to determine what URL to initially open for the test
  534. *
  535. * @return The base URL for the test. Does not include a trailing slash.
  536. */
  537. protected String getBaseURL() {
  538. return "http://" + getDeploymentHostname() + ":" + getDeploymentPort();
  539. }
  540. /**
  541. * Generates the application id based on the URL in a way compatible with
  542. * VaadinServletService.
  543. *
  544. * @param pathWithQueryParameters
  545. * The path part of the URL, possibly still containing query
  546. * parameters
  547. * @return The application ID string used in Vaadin locators
  548. */
  549. private String getApplicationId(String pathWithQueryParameters) {
  550. // Remove any possible URL parameters
  551. String pathWithoutQueryParameters = pathWithQueryParameters.replaceAll(
  552. "\\?.*", "");
  553. if ("".equals(pathWithoutQueryParameters)) {
  554. return "ROOT";
  555. }
  556. // Retain only a-z and numbers
  557. return pathWithoutQueryParameters.replaceAll("[^a-zA-Z0-9]", "");
  558. }
  559. /**
  560. * Helper method for sleeping X ms in a test. Catches and ignores
  561. * InterruptedExceptions
  562. *
  563. * @param timeoutMillis
  564. * Number of ms to wait
  565. */
  566. protected void sleep(int timeoutMillis) {
  567. try {
  568. Thread.sleep(timeoutMillis);
  569. } catch (InterruptedException e) {
  570. throw new RuntimeException(e);
  571. }
  572. }
  573. /**
  574. * Provides helper method for selecting the browser to run on
  575. *
  576. * @author Vaadin Ltd
  577. */
  578. public static class BrowserUtil {
  579. /**
  580. * Gets the capabilities for Safari of the given version
  581. *
  582. * @param version
  583. * the major version
  584. * @return an object describing the capabilities required for running a
  585. * test on the given Safari version
  586. */
  587. public static DesiredCapabilities safari(int version) {
  588. DesiredCapabilities c = DesiredCapabilities.safari();
  589. c.setVersion("" + version);
  590. return c;
  591. }
  592. /**
  593. * Gets the capabilities for Chrome of the given version
  594. *
  595. * @param version
  596. * the major version
  597. * @return an object describing the capabilities required for running a
  598. * test on the given Chrome version
  599. */
  600. public static DesiredCapabilities chrome(int version) {
  601. DesiredCapabilities c = DesiredCapabilities.chrome();
  602. c.setVersion("" + version);
  603. c.setPlatform(Platform.XP);
  604. return c;
  605. }
  606. /**
  607. * Gets the capabilities for Opera of the given version
  608. *
  609. * @param version
  610. * the major version
  611. * @return an object describing the capabilities required for running a
  612. * test on the given Opera version
  613. */
  614. public static DesiredCapabilities opera(int version) {
  615. DesiredCapabilities c = DesiredCapabilities.opera();
  616. c.setVersion("" + version);
  617. c.setPlatform(Platform.XP);
  618. return c;
  619. }
  620. /**
  621. * Gets the capabilities for Firefox of the given version
  622. *
  623. * @param version
  624. * the major version
  625. * @return an object describing the capabilities required for running a
  626. * test on the given Firefox version
  627. */
  628. public static DesiredCapabilities firefox(int version) {
  629. DesiredCapabilities c = DesiredCapabilities.firefox();
  630. c.setVersion("" + version);
  631. c.setPlatform(Platform.XP);
  632. return c;
  633. }
  634. /**
  635. * Gets the capabilities for Internet Explorer of the given version
  636. *
  637. * @param version
  638. * the major version
  639. * @return an object describing the capabilities required for running a
  640. * test on the given Internet Explorer version
  641. */
  642. public static DesiredCapabilities ie(int version) {
  643. DesiredCapabilities c = DesiredCapabilities.internetExplorer();
  644. c.setVersion("" + version);
  645. return c;
  646. }
  647. /**
  648. * Checks if the given capabilities refer to Internet Explorer 8
  649. *
  650. * @param capabilities
  651. * @return true if the capabilities refer to IE8, false otherwise
  652. */
  653. public static boolean isIE8(DesiredCapabilities capabilities) {
  654. return BrowserType.IE.equals(capabilities.getBrowserName())
  655. && "8".equals(capabilities.getVersion());
  656. }
  657. /**
  658. * Returns a human readable identifier of the given browser. Used for
  659. * test naming and screenshots
  660. *
  661. * @param capabilities
  662. * @return a human readable string describing the capabilities
  663. */
  664. public static String getBrowserIdentifier(
  665. DesiredCapabilities capabilities) {
  666. String browserName = capabilities.getBrowserName();
  667. if (BrowserType.IE.equals(browserName)) {
  668. return "InternetExplorer";
  669. } else if (BrowserType.FIREFOX.equals(browserName)) {
  670. return "Firefox";
  671. } else if (BrowserType.CHROME.equals(browserName)) {
  672. return "Chrome";
  673. } else if (BrowserType.SAFARI.equals(browserName)) {
  674. return "Safari";
  675. } else if (BrowserType.OPERA.equals(browserName)) {
  676. return "Opera";
  677. }
  678. return browserName;
  679. }
  680. /**
  681. * Returns a human readable identifier of the platform described by the
  682. * given capabilities. Used mainly for screenshots
  683. *
  684. * @param capabilities
  685. * @return a human readable string describing the platform
  686. */
  687. public static String getPlatform(DesiredCapabilities capabilities) {
  688. if (capabilities.getPlatform() == Platform.WIN8
  689. || capabilities.getPlatform() == Platform.WINDOWS
  690. || capabilities.getPlatform() == Platform.VISTA
  691. || capabilities.getPlatform() == Platform.XP) {
  692. return "Windows";
  693. } else if (capabilities.getPlatform() == Platform.MAC) {
  694. return "Mac";
  695. }
  696. return capabilities.getPlatform().toString();
  697. }
  698. /**
  699. * Returns a string which uniquely (enough) identifies this browser.
  700. * Used mainly in screenshot names.
  701. *
  702. * @param capabilities
  703. *
  704. * @return a unique string for each browser
  705. */
  706. public static String getUniqueIdentifier(
  707. DesiredCapabilities capabilities) {
  708. return getUniqueIdentifier(getPlatform(capabilities),
  709. getBrowserIdentifier(capabilities),
  710. capabilities.getVersion());
  711. }
  712. /**
  713. * Returns a string which uniquely (enough) identifies this browser.
  714. * Used mainly in screenshot names.
  715. *
  716. * @param capabilities
  717. *
  718. * @return a unique string for each browser
  719. */
  720. public static String getUniqueIdentifier(
  721. DesiredCapabilities capabilities, String versionOverride) {
  722. return getUniqueIdentifier(getPlatform(capabilities),
  723. getBrowserIdentifier(capabilities), versionOverride);
  724. }
  725. private static String getUniqueIdentifier(String platform,
  726. String browser, String version) {
  727. return platform + "_" + browser + "_" + version;
  728. }
  729. }
  730. /**
  731. * Called by the test runner whenever there is an exception in the test that
  732. * will cause termination of the test
  733. *
  734. * @param t
  735. * the throwable which caused the termination
  736. */
  737. public void onUncaughtException(Throwable t) {
  738. // Do nothing by default
  739. }
  740. }