Libraries ScalaTest + Play ScalaTest + Selenium ScalaTest + ScalaCheck ScalaTest + JUnit 4 ScalaTest + JUnit 5 ScalaTest + TestNG ScalaTest + EasyMock ScalaTest + JMock ScalaTest + Mockito |
Using SeleniumScalaTest + Selenium includes a domain specific language (DSL) for writing browser-based tests using Selenium. To use ScalaTest's Selenium DSL, you'll first need to add ScalaTest + Selenium to your project dependencies. For example, in your sbt build you might add: libraryDependencies += "org.scalatestplus" %% "selenium-4-21" % "3.2.19.0" % "test" Note, that the selected selenium version for the sclatestplus library should reflect the version you have used for selenium-java and the version itself is derived from the scalatest core library being used. For following examples illustration purpose, we'll add in another two scalatest dependencies for FlatSpec style trait and Should Matchers DSL:libraryDependencies += "org.scalatest" %% "scalatest-flatspec" % "3.2.19" % "test" libraryDependencies += "org.scalatest" %% "scalatest-shouldmatchers" % "3.2.19" % "test" Then mix trait
import org.scalatest._ import org.scalatest.matchers._ import org.scalatestplus.selenium._ import org.openqa.selenium.WebDriver import org.openqa.selenium.htmlunit.HtmlUnitDriver class BlogSpec extends flatspec.AnyFlatSpec with should.Matchers with WebBrowser { implicit val webDriver: WebDriver = new HtmlUnitDriver val host = "http://localhost:9000/" "The blog app home page" should "have the correct title" in { go to (host + "index.html") pageTitle should be ("Awesome Blog") } } For convenience, however, ScalaTest provides a import org.scalatest._ import org.scalatest.matchers._ import org.scalatestplus.selenium._ class BlogSpec extends flatspec.AnyFlatSpec with should.Matchers with HtmlUnit { val host = "http://localhost:9000/" "The blog app home page" should "have the correct title" in { go to (host + "index.html") pageTitle should be ("Awesome Blog") } } The web driver traits provided by ScalaTest are:
NavigationYou can ask the browser to retrieve a page (go to a URL) like this:
go to "http://www.artima.com"
Note: If you are using the page object pattern, you can also go to a page using the Once you have retrieved a page, you can fill in and submit forms, query for the values of page elements, and make assertions.
In the following example, selenium will go to go to "http://www.google.com" click on "q" textField("q").value = "Cheese!" submit() // Google's search is rendered dynamically with JavaScript. eventually { title should be ("Cheese! - Google Search") } In the above example, the Alternatively, you can be more specific: click on id("q") // to lookup by id "q" click on name("q") // to lookup by name "q" In addition to
For example, you can select by link text with:
click on linkText("click here!")
If an element is not found via any form of lookup, evaluation will complete abruptly with a Getting and setting input element valuesScalaTest's Selenium DSL provides a clear, simple syntax for accessing and updating the values of input elements such as text fields, radio buttons, checkboxes, and selection lists. If a requested element is not found, or if it is found but is not of the requested type, an exception will immediately result causing the test to fail. Text fields and text areasYou can change a text field's value by assigning it via the textField("q").value = "Cheese!" And you can access a text field's value by simply invoking textField("q").value should be ("Cheese!") If the text field is empty, You can use the same syntax with text areas by replacing textArea("body").value = "I saw something cool today!" textArea("body").value should be ("I saw something cool today!") Radio buttonsRadio buttons work together in groups. For example, you could have a group of radio buttons, like this: <input type="radio" name="group1" value="Option 1"> Option 1</input> <input type="radio" name="group1" value="Option 2"> Option 2</input> <input type="radio" name="group1" value="Option 3"> Option 3</input> You can select an option in either of two ways: radioButtonGroup("group1").value = "Option 2" radioButtonGroup("group1").selection = Some("Option 2") Likewise, you can read the currently selected value of a group of radio buttons in two ways: radioButtonGroup("group1").value should be ("Option 2") radioButtonGroup("group1").selection should be (Some("Option 2")) If the radio button has no selection at all, CheckboxesA checkbox in one of two states: selected or cleared. Here's how you select a checkbox:
checkbox("cbx1").select()
And here's how you'd clear one:
checkbox("cbx1").clear()
You can access the current state of a checkbox with checkbox("cbx1").isSelected should be (true) Single-selection dropdown listsGiven the following single-selection dropdown list: <select id="select1"> <option value="option1">Option 1</option> <option value="option2">Option 2</option> <option value="option3">Option 3</option> </select> You could select singleSel("select1").value = "option2" singleSel("select1").selection = Some("option2") To clear the selection, either invoke singleSel.clear() singleSel("select1").selection = None You can read the currently selected value of a single-selection list in the same manner as radio buttons: singleSel("select1").value should be ("option2") singleSel("select1").selection should be (Some("option2")) If the single-selection list has no selection at all, Multiple-selection listsGiven the following multiple-selection list: <select name="select2" multiple="multiple"> <option value="option4">Option 4</option> <option value="option5">Option 5</option> <option value="option6">Option 6</option> </select> You could select multiSel("select2").values = Seq("option5", "option6") The previous command would essentially clear all selections first, then select multiSel("select2").values += "option5" multiSel("select2").values += "option6" To clear a specific option, pass its name to multiSel("select2").clear("option5") To clear all selections, call
multiSel("select2").clearAll()
You can access the current selections with multiSel("select2").values should have size 2 multiSel("select2").values(0) should be ("option5") multiSel("select2").values(1) should be ("option6") Clicking and submittingYou can click on any element with “ click on "aButton" click on name("aTextField") If the requested element is not found, Clicking on a input element will give it the focus. If current focus is in on an input element within a form, you can submit the form by
calling submit() SwitchingYou can switch to a popup alert using the following code: switch to alert to switch to a frame, you could: switch to frame(0) // switch by index switch to frame("name") // switch by name If you have reference to a window handle (can be obtained from calling windowHandle/windowHandles), you can switch to a particular window by: switch to window(windowHandle) Similar to what you got in Selenium, you can also switch to active element and default content: switch to activeElement switch to defaultContent Navigation historyIn real web browser, you can press the 'Back' button to go back to previous page. To emulate that action in your test, you can call goBack() To emulate the 'Forward' button, you can call: goForward() And to refresh or reload the current page, you can call: reloadPage() Cookies!To create a new cookie, you'll say: add cookie ("cookie_name", "cookie_value") to read a cookie value, you do: // If value is undefined, throws TFE right then and there. Never returns null. cookie("cookie_name").value should be ("cookie_value") In addition to the common use of name-value cookie, you can pass these extra fields when creating the cookie, available ways are:
cookie(name: String, value: String) cookie(name: String, value: String, path: String) cookie(name: String, value: String, path: String, expiry: Date) cookie(name: String, value: String, domain: String, path: String, expiry: Date) cookie(name: String, value: String, domain: String, path: String, expiry: Date, secure: Boolean) and to read those extra fields:
cookie("cookie_name").value // Read cookie's value cookie("cookie_name").path // Read cookie's path cookie("cookie_name").expiry // Read cookie's expiry cookie("cookie_name").domain // Read cookie's domain cookie("cookie_name").isSecure // Read cookie's isSecure flag In order to delete a cookie, you could use the following code:
delete cookie "cookie_name"
or to delete all cookies in the same domain:- delete all cookies Implicit waitTo set the implicit wait, you can call implicitlyWait method: implicitlyWait(Span(10, Seconds)) Page source and current URLIt is possible to get the html source of currently loaded page, using: pageSource and if needed, get the current URL of currently loaded page: currentUrl Screen captureYou can capture screen using the following code:
val file = capture
By default, the captured image file will be saved in temporary folder (returned by java.io.tmpdir property), with random file name ends with .png extension. You can specify a fixed file name:
capture to "MyScreenShot.png"
or
capture to "MyScreenShot"
Both will result in a same file name You can also change the target folder screenshot file is written to, by saying:
setCaptureDir("/home/your_name/screenshots")
If you want to capture a screenshot when something goes wrong (e.g. test failed), you can
use
withScreenshot { assert("Gold" == "Silver", "Expected gold, but got silver") } In case the test code fails, you'll see the screenshot location appended to the error message, for example:
Expected gold but got silver; screenshot capture in /tmp/AbCdEfGhIj.png Using the page object patternIf you use the page object pattern, mixing trait class HomePage extends Page { val url = "localhost:9000/index.html" } Executing JavaScriptTo execute arbitrary JavaScript, for example, to test some JavaScript functions on your page, pass it to go to (host + "index.html") val result1 = executeScript("return document.title;") result1 should be ("Test Title") val result2 = executeScript("return 'Hello ' + arguments[0]", "ScalaTest") result2 should be ("Hello ScalaTest") To execute an asynchronous bit of JavaScript, pass it to val script = """ var callback = arguments[arguments.length - 1]; window.setTimeout(function() {callback('Hello ScalaTest')}, 500); """ setScriptTimeout(1 second) val result = executeAsyncScript(script) result should be ("Hello ScalaTest") Querying for elementsYou can query for arbitrary elements via val ele: Option[Element] = find("q") Cleaning upTo close the current browser window, and exit the driver if the current window was the only one remaining, use close() To close all windows, and exit the driver, use quit() |
ScalaTest is brought to you by Bill Venners and Artima.
ScalaTest is free, open-source software
released under the Apache
2.0 license.
If your company loves ScalaTest, please consider sponsoring the project.
Copyright © 2009-2024 Artima, Inc. All Rights Reserved.