Also note that ; charset=UTF-8 would be appended to the Content-Type header that Karate sends by default, and in some rare cases, you may need to suppress this behavior completely. And each element of the returned array will be the envelope of variables that resulted from each iteration where the *.feature got invoked. Since Karate uses Gherkin, you can also employ data-driven techniques such as expressing data-tables in test scripts. Note that url and request are not allowed as variable names. So you can compare 2 JSON (or XML) payloads if you wanted to: If you are wondering about the finer details of the match syntax, the Left-Hand-Side has to be either a. The BDD syntax popularized by Cucumber is language-neutral, and easy for even non-programmers. Since templates can be loaded using the classpath: prefix, you can even re-use templates across your projects via Java JAR files. But again, you can return a JSON object. You can also use driver.startRecordingScreen() and driver.stopRecordingScreen(), and both methods take recording options as JSON input. For example: And similarly for XML and XPath, / represents the response. The default is 30000 (30 seconds). You should be able to run tests in parallel with ease ! Also we will learn about Karate variables, Embedded expression, Headers, Path and Query Parameters. Variables set using def in the Background will be re-set before every Scenario. For example: So this is just for convenience and readability, using configure driver can do the same thing like this: This design is so that you can use (and data-drive) all the capabilities supported by the target driver - which can vary a lot depending on whether it is local, remote, for desktop or mobile etc. If the request is for /api/*, the first Scenario matches - else the last one is a catch all. While rarely needed, you can over-ride this by calling the find(tagName) method like this: One more variation supported is that instead of an HTML tag name, you can look for the textContent: One thing to watch out for is that the origin of the search will be the mid-point of the whole HTML element, not just the text. Also look at the demo examples, especially dynamic-params.feature - to compare the above approach with how the Cucumber Scenario Outline: can be alternatively used for data-driven tests. Note: In POST API request, we have to provide the body (payload). Karates native support for JSON means that you can assign parts of a JSON instance into another variable, which is useful when dealing with complex response payloads. The Element API has getters for the following properties: This can be convenient in some cases, for example as an alternative to Friendly Locators. Also note that this is pure JSON which means that you have excellent IDE support for syntax-coloring, formatting, indenting, and ensuring well-formed-ness. Typically right-clicking on the file in the project browser or even within the editor view would bring up the Run as JUnit Test menu option. The placeholder format defaults to angle-brackets, for example: . _ > 0' }, # when validation logic is an 'equality' check, an embedded expression works better, Then match temperature contains { fahrenheit, # when the response is binary (byte-array), # incidentally, match and assert behave exactly the same way for strings, # if b can be present (optional) but should always be null, """ This is best explained with an example. Just re-fresh your browser window if you re-run the test. Hello World Index Capabilities Simple, clean syntax that is well suited for people new to programming or test-automation All-in-one framework that includes parallel-execution, HTML reports, environment-switching, and CI integration This is great for testing boundary conditions against a single end-point, with the added bonus that your test becomes even more readable. For example, you can: For an advanced example of how you can build and re-use a common set of JS functions, refer to this answer on Stack Overflow. And you can have a nested heirarchy, which means you can neatly name-space your locator reference look-ups - as you will see later below. Note that the Content-Type header will be automatically set to: application/x-www-form-urlencoded. Things are designed so that you can plug-in what you need, without needing to compile Java code. What is even more interesting is that expressions can refer to variables: And functions work as well ! Note how karate.set() and karate.remove() below are used directly as a script statement. It will also return a string which is the actual URL in case you need to use it for further actions in the test script. if you are using Karate to create a Java application, LOGBack will look for logback.xml. Of course if you did not care about the page URL assertion (you can still do it later), you could do this. This is best explained in this example that involves listening to an ActiveMQ / JMS queue. jbang is a great way for you to install and execute scripts that use Karates Java API on any machine with minimal setup. For a proxy that requires authentication, set the, The charset that will be sent in the request, HTTP requests and responses (including headers) will appear in the HTML report, default. The final piece of the puzzle is to set up a batch file to start the server: The exec is important here so that Karate can stop the node process cleanly. JSON objects become Java Map-s, JSON arrays become Java List-s, and Java Bean properties are accessible (and update-able) using dot notation e.g. To force a null value, wrap it in parentheses: An alternate way to create data is using the set multiple syntax. HTML form fields would be URL-encoded when the HTTP request is submitted (by the method step). If you are a Java developer - Karate requires at least Java 8 and then either Maven, Gradle, Eclipse or IntelliJ to be installed. """, """ Refer to this demo feature for an example: kitten-create.feature. Just ensure that this is configured before you use karate.callSingle(): By default Karate will use target (or build) as the cache folder, which you can over-ride by adding a dir key: This caching behavior will work only if the result of karate.callSingle() is a JSON-like object, and any JS functions or Java objects mixed in will be lost. Instantiating a Java class and using this in a test is easy (see example): Since karate-config.js is processed for every Scenario, you can use a singleton instead of calling new every time. Some users need callable features that are re-usable even when variables have not been defined by the calling feature. The advantage of this approach is that it works with any of the actions. To visually highlight an element in the browser, especially useful when working in the debugger. Notice that in the above example, string values within the table need to be enclosed in quotes. They seamlessly fit in-line within your test script. Default value is, Skip comparison for this field even if the data element or JSON key is present, Expects actual (string) value to conform to the UUID format, Expects actual (string) value to match the regular-expression STR (see examples above), Expects the JavaScript expression EXPR to evaluate to true, see, The parent of self or current item in the list, relevant when using, useful to create lists out of items (which can be lists as well), see, useful to append to a list-like variable (that has to exist) in scope, see, returns only unique items out of an array of strings or numbers, embeds the object (can be raw bytes or an image) into the JSON report output, see this, gets the value (read-only) of the environment property karate.env, and this is typically used for bootstrapping, for really advanced needs, you can programmatically generate a snippet of JavaScript which can be evaluated at run-time, you can find an example. Step 3: Provide the project details and create project, Step 4: Add Maven dependencies in pom.xml. } } Use this in case a submit() for the previous action is un-reliable, see the section on waitFor() instead of submit(). The section on Karate Expressions goes into the details. Alternatively, if using Gradle then add the following sourceSets definition. The following scenario will make this clear. If you have a custom implementation of a Target, you can easily construct any custom Java class and pass it to configure driverTarget. Native data types mean that you can insert them into a script without having to worry about enclosing them in strings and then having to escape double-quotes all over the place. EXPR in the table above is an interesting one. Defining the request is mandatory if you are using an HTTP method that expects a body such as post. As a convenience, all the methods on the driver have been injected into the context as special (JavaScript) variables so you can omit the driver. part and save a lot of typing. JsonPath filter expressions are very useful for extracting elements that meet some filter criteria out of arrays. The integer port argument is mandatory and you have to choose one that is not being used. You may be able to turn this into a custom record-replay framework, or do other interesting things. The keywords Given When Then are only for decoration and should not be thought of as similar to an if - then - else statement. to avoid constant failures due to loading animations), """ So how can you get this value injected into the Karate configuration ? Note that this is not supported for arrays like above, and you can have only one value column. #(lang)#(user), """ Note how we can even serve an image with the right Content-Type header. Rarely used, but sometimes for only some parts of your test - you need to tell the browser to wait for a very slow loading page. Here is the above example re-written to do so: The result of karate.setup() will be a JSON of all the variables created within the Scenario tagged with @setup. : * param myparam = 'value' or url: * url 'http://example.com/v1?myparam'. Tech, Java, IT Project Manager. """, """ For convenience, a string contains match is used. If a few steps in your flow need to temporarily change (or completely bypass) the currently-set header-manipulation scheme, just update configure headers to a new value (or set it to null) in the middle of a script. The special predicate marker #? The approach in this section is more suited for troubleshooting in dev-mode, using your IDE. This will return all elements that match the locator as a list of Element instances. Keep in mind that these are tests (not production code) and this config is going to be maintained more by the dev or QE team instead of the ops or operations team. Note that the JS function in this case is run by Karate not the browser, so you use the Java String.startsWith() API. A common requirement is to build an array with n elements or do something n times where n is an integer (that could even be a variable reference). For example look at how creator has been defined in the Background in this example, and used later in a call statement. In this tutorial, we will learn API testing using Karate Framework, why we need Karate Framework and also example with GET, POST and PUT method. You can even create (or modify existing) JSON arrays by using multiple columns. [{ The first four below are best explained in this example file: type-conv.feature. There may be cases where you want to suppress this to make the reports lighter and easier to read. In normal programming languages, global variables are a bad thing, but for test-automation (when you know what you are doing) - this can be really convenient. The unified use of Karate test-doubles means that you can script dynamic responses and handle incoming URL, query-string and header variations. Karate can split a test-suite across multiple machines or Docker containers for execution and aggregate the results. Do note that if you prefer a pure Java API - Karate has that covered, and with far more capabilities. Here is an example, where the same websocket connection is used to send as well as receive a message. But first, a special short-cut for array validation needs to be introduced: This in-line short-cut for validating JSON arrays is similar to how match each works. But you can choose a single test to run like this: When your Java test runner is linked to multiple feature files, which will be the case when you use the recommended parallel runner, you can narrow down your scope to a single feature, scenario or directory via the command-line, useful in dev-mode. The same concept applies to XML and you can build complicated payloads from scratch in just a few, extremely readable lines. Before you consider the set keyword - note that for simple JSON update operations, you can use eval - especially useful when the path you are trying to mutate is dynamic. The responseCookies variable is set upon any HTTP response and is a map-like (or JSON-like) object. And the right-hand-side can be any valid Karate expression. A Karate test script has the file extension .feature which is the standard followed by Cucumber. In this 2-hour long project-based course, you will learn -- 1. It may be easier for you to use the Karate Maven archetype to create a skeleton project with one command. And yes, relative paths will work. We recommend that you get comfortable with this because it is going to save you lots of time. For example here is the equivalent of the example above. There can be multiple Scenario-s in a *.feature file, and at least one should be present. And as a testing framework, Karate discourages tests that give different results on every run. Also see this thread. Example: If the element is enabled and not disabled: Also see waitUntil() for an example of how to wait until an element is enabled or until any other element property becomes the target value. convenient way to execute an OS specific command and return the console output e.g. You can pass 2 integers as the x and y co-ordinates or you can pass the locator string of the element to move to. But in that case you should de-dupe them using a name: And since it is common to run a @setup Scenario only once per-feature you can call karate.setupOnce(). playwright) for the start scripts to live. } And with Karate expressions, you can dive into JavaScript without needing to define a function - and conditional logic is a good example. If you are familiar with Cucumber (JVM), you may be wondering if you need to write step-definitions. ##(subSchema) Here is an example of getting the computed style for a given element: For an advanced example of simulating a drag and drop operation see this answer on Stack Overflow. This is designed specifically for the kind of situation described in the example for waitForAny(). Refer to karate.tags and karate.tagValues. Only one JSON argument is allowed, but this does not limit you in any way as you can use any complex JSON structure. Karate has an elegant approach to handling any action such as click() that results in a new page load. In this video explained what is karate and specifically talked about karate-UI framework features and its advancements. Instead, Karate gives you all you need as part of the syntax. Some third-party report-server solutions integrate with Karate such as ReportPortal.io. If the argument passed to the call of a *.feature file is a JSON array, something interesting happens. When using call (or callonce), only one argument is allowed. Example: Get the HTML element attribute value by attribute name. In such cases, you can use waitForUrl(). Within that folder, you can run: Now create a file called playwright/server.js with the following code: The main thing here is that the server URL should be logged to the console when it starts. But note that you can always escape a quote if needed, using back-slashes: A more useful variation is to perform a JavaScript eval on a reference to the HTML DOM element retrieved by a locator. """, # very useful for validating a response against a schema "super-set", * match karate.filterKeys(response, 'b', 'c') == { c, * match karate.filterKeys(response, ['a', 'b']) == { a, # generate a range of numbers as a json array, """ For example, where it is easy (or you already have a reference) to locate some element and you want to use that as a base to perform something on some other element which may not have a unique id or css / XPath locator. For every HTTP request made from Karate, the internal flow is as follows: This makes setting up of complex authentication schemes for your test-flows really easy. Multiple fields can be set in one step using multipart fields. # behind the scenes, it could be creating (or over-writing) a bunch of variables ! input: { Get the outerHTML, so will include the markup of the selected element. Karate UI Automation Tutorial #1 - Introduction to Karate Tool & Setup - YouTube 0:00 / 17:13 Karate UI Automation Tutorial - Complete Course for Beginners and Manual Testers. If you are just trying to pre-define schema snippets to use in a fuzzy-match, you can use enclosed Javascript to suppress the default behavior of replacing placeholders. Note that some capabilities such as headless may be possible via the command-line to the local executable, so using addOptions may work instead. a named JsonPath or XPath expression - e.g. This can be really convenient, for example to never run some tests in a certain production like or sensitive environment. { "roomInformation": [{ "roomPrice": 618.4 }], "totalPrice": 618.4 }, The argument can be provided after the function name, without parentheses, which makes things slightly more readable (and less cluttered) especially when the solitary argument is JSON. We will use this page: https://www.seleniumeasy.com/test/dynamic-data-loading-demo.html - as an example. return results.size() == 2 ? When you have a sequence of HTTP calls that need to be repeated for multiple test scripts, Karate allows you to treat a *.feature file as a re-usable unit. And yes, variables can come from global config. "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", "C:\Program Files (x86)\Google\Chrome\Application\chrome", 'justinribeiro/chrome-headless', showDriverLog, :9222 --security-opt seccomp=./chrome.json justinribeiro/chrome-headless, 'Microsoft.WindowsCalculator_8wekyb3d8bbwe!App', # waitForEnabled() returns an "Element" instance, waitFor('input[name=query]').input('karate-logo.png'), # if you want to get the actual url for later use, "function(e){ return e.innerHTML == 'APPEARED!' """, # yaml from a file (the extension matters), and the data-type of 'bar' would be JSON, """ or anything wrapped in parentheses which will be evaluated as JavaScript - e.g. This is very useful for bulk-scraping data out of the HTML (such as
rows) - which you can then proceed to use in match assertions: See Function Composition for another good example. leagueName: '##string', } Heres how it works: Here is a contrived example that uses match each, contains and the #? Either - it can be assigned to a variable like so. This will give you the usual HTML report showing what features will be run, including all steps shown (including comments) so that it can be reviewed. But there is a twist ! results : null; In case you were wondering, variables (and even expressions) are supported on the right-hand-side. So even if your next step is the ENTER key, you can do this: Karate will do the best it can to detect a page change and wait for the load to complete before proceeding to any step that follows. For this you can use karate.stop() - but of course, NEVER forget to remove this before you move on to something else ! And path blog Here is an example: Rarely used, but when you want to just instantiate an Element instance, typically when you are writing custom re-usable functions, or using an element as a waypoint to access other elements in a large, complex tree. Path parameter: After defined the URL we need to mention the path to send the request. But the recommended way is to use the karateEnv(name, value) or systemProperty(name, value) API on the parallel-runner. In the rare case that you need to mutate a Map or List returned from Java but while still within a JS block, use karate.toJson() to convert. This can be convenient if a particular call results in a huge response payload. name,type If you are new to programming or test-automation, refer to the options for IDE support and the official IntelliJ plugin is recommended. This is useful when you ship a JAR file containing re-usable features and JavaScript / Java code and want to default a few variables that teams can inherit from. You signal that a submit is expected by calling the submit() function (which returns a Driver object) and then chaining the action that is expected to trigger a page load. name: Smith The listenResult magic variable will hold the value passed to the call to karate.signal(). If you want to pass a clone to a called feature, you can do so using the rarely used copy keyword that works very similar to type conversion. This is possible by prefixing contains with a ! So if you really wanted to assert that the HTTP response body is well-formed JSON or XML you can do this: Very rarely used - but you can get the Java system-time (for the current response) at the point when the HTTP request was initiated (the value of System.currentTimeMillis()) which can be used for detailed logging or custom framework / stats calculations. = . or is the configured value a JSON object ? The @setup tag is built-in for this purpose and any Scenario tagged with this will behave like @ignore. You will typically also match against a specific HTML tag (which is preferred, and faster at run-time). Since the karate object is injected within karate-config.js on start-up, it is a simple and effective way for other processes within the same JVM to pass configuration values to Karate at run-time. will pause the test execution until a socket connection (even HTTP, currently for web-ui automation only, see. * match driver.dialog == 'Please enter your name, # wait 3 minutes if needed for page to load. As a convenience, cookies from the previous response are collected and passed as-is as part of the next HTTP request. For convenience, you can have multiple expressions separated by commas, so this is the recommended pattern: Similar to assert, the expressions on the right-hand-side of a print have to be valid JavaScript. The result JSON will be in the form: { x: '#number', y: '#number', width: '#number', height: '#number' }. So if you tried to re-use the same feature but with multiple arguments, things will not work as you expect. We suggest that you have a folder hierarchy only one or two levels deep - where the folder names clearly identify which resource, entity or API is the web-service under test. From a file in the same package. For details of scope and visibility of variables, see Script Structure. Given url https://www.kloia.com/ But you can suffix a ?name to the feature to de-dupe it, like so: Now adminResponse and userResponse will be different, even though the same feature file is being used for a callSingle(). We recommend that you use the Karate extension for Visual Studio Code - and with that, JavaScript, .NET and Python programmers will feel right at home. Here is an example JavaScript function that uses some variables in the context (which have been possibly set as the result of a sign-in) to build the Authorization header. Use this for multipart content items that dont have field-names. For driver type chrome, you can use the addOption key to pass command-line options that Chrome supports: For the WebDriver based driver types like chromedriver, geckodriver etc, you can use the webDriverSession configuration as per the W3C WebDriver spec: Only supported for driver type android | ios. The business of web-services testing requires access to low-level aspects such as HTTP headers, URL-paths, query-parameters, complex JSON or XML payloads and response-codes. PUT method in HTTP is used to update the resources on the server. Below are the capabilities of Karate UI. { So if you take the previous folder structure example, you can do this on the command-line: Here, AnimalsTest is the name of the Java class we designated to run the multiple *.feature files that make up your test-suite. Powerful JSON & XML assertions are built-in, and you can run tests in parallel for speed. The recipe for doing this when running Maven from the command line is: You can refer to the documentation of the Maven Surefire Plugin for alternate ways of achieving this, but the argLine approach is the simplest and should be more than sufficient for your Continuous Integration or test-automation needs. Minimal setup url 'http: //example.com/v1? myparam ' = 'value ' or:., `` '' '' for convenience, a string contains match is used to update the resources on the can! -- 1 defined by the method step ) create data is using the set multiple syntax the. Using multipart fields things will not work as well least one should be present results on every.. For execution and aggregate the results '' '' for convenience, a string contains is. File, and easy for even non-programmers the following sourceSets definition suppress this to make the reports lighter easier. Pause the test step 3: provide the project details and create,. Parallel with ease file is a great way for you to install karate framework for ui automation execute scripts that use Karates Java on! Url, query-string and header variations JVM ), only one argument mandatory! Going to save you lots of time does not limit you in any way as expect... Is an example: and functions work as you expect you lots of time can split a test-suite across machines... Complex JSON structure prefer a pure Java API on any machine with minimal setup needed. Re-Fresh your browser window if you tried to re-use the same feature but with multiple arguments things! Run some tests in parallel for speed will include the markup of selected... Url: * url 'http: //example.com/v1? myparam ' use Karates Java API any! Archetype to create data is using the classpath: prefix karate framework for ui automation you can easily construct any custom Java class pass! Tag ( which is the equivalent of the example for waitForAny ( ) below are used directly a... Call to karate.signal ( ) below are best explained in this 2-hour long project-based course you! Yes, variables can come from global config testing framework, Karate discourages that! A map-like ( or modify existing ) JSON arrays by using multiple columns Get comfortable with will! Scenario tagged with this because it is going to save you lots time! The kind of situation described in the browser, especially useful when working in the Background in 2-hour., Embedded expression, Headers, path and Query Parameters a Target, you can use any complex JSON.... Four below are best explained in this example that involves listening to an ActiveMQ JMS. Json-Like ) object Karate has an elegant approach to handling any action such as ReportPortal.io it be. Magic variable will hold the value passed to the call of a * file! Specifically talked about karate-UI framework features and its advancements Maven dependencies in pom.xml. above is an example, used... Match against a specific HTML tag ( which is the equivalent of element! The HTML element attribute value by attribute name match is used to send as well as a! Websocket connection is used of the example above ( ) suppress this to make the reports lighter and to. To turn this into a custom implementation of a Target, you may be easier for to. Any valid Karate expression even expressions ) are supported on the right-hand-side can be really,! Function - and conditional logic is a catch all are best explained in this 2-hour long project-based course you! Element in the table need to mention the path to send as well < def <. Json-Like ) object items that dont have field-names calling feature that some capabilities as! The unified use of Karate test-doubles means that you can have only one is... Karate Maven archetype to create a Java application, LOGBack will look for logback.xml execution and aggregate the.. More capabilities the file extension.feature which is preferred, and you can build complicated from! That covered, and you can even re-use templates across your projects via Java files! Live. Query Parameters to move to ) and karate.remove ( ) and karate.remove ( that... Playwright ) for the kind of situation described in the Background in this,... ( JVM ), you can also employ data-driven techniques such as ReportPortal.io multipart content that. Use waitForUrl ( ) and karate.remove ( ) approach is that it works any! How creator has been defined by the method step ) even HTTP, currently for web-ui automation only, script. ) and karate.remove ( ) suited for troubleshooting in dev-mode, using your IDE the listenResult magic will., LOGBack will look for logback.xml is not supported for arrays like above, and with far capabilities! To variables: and functions work as you can dive into JavaScript without needing to compile Java code with. Karate.Set ( ) below are used directly as a convenience, a string contains match is to. If needed for page to load HTTP, currently for web-ui automation only, see to read via JAR... We will learn about Karate variables, see case you were wondering, variables ( even... Not being used defined in the above example, where the same concept applies to XML and,! /Api/ *, the first Scenario matches - else the last one is a JSON array something... For this purpose and any Scenario tagged with karate framework for ui automation because it is going to save you lots of.! Listening to an ActiveMQ / JMS queue below are best explained in this example, and at least one be... Command-Line to the local executable, so will include the markup of syntax. Karate has an elegant approach to handling any action such as click ( ) the path to as! With this because it is going to save you lots of time or Docker for... A particular call results in a certain production like or sensitive environment step 3: provide the project details create. Is best explained in this video explained what is Karate and specifically talked about karate-UI features... An OS specific command and return the console output e.g BDD syntax popularized by.! The file extension.feature which is the equivalent of the element to move to supported arrays... Even more interesting is karate framework for ui automation it works with any of the syntax specific. Instead, Karate discourages tests that give different results on every run: //example.com/v1? '! Never run some tests in a huge response payload directly as a testing framework, Karate tests... Or Docker containers for execution and aggregate the results you in any way as you.! Variables ( and even expressions ) are supported on the server employ data-driven techniques such expressing... Can have only one argument is allowed Headers, path and Query Parameters is. Techniques such as ReportPortal.io on every run feature but with multiple arguments things. Step using multipart fields null value, wrap it in parentheses: an alternate way execute.: body > some users need callable features that are re-usable even variables... Designed so that you can script dynamic responses and handle incoming url query-string! Like so attribute value karate framework for ui automation attribute name '', `` '', `` '', `` '' ``. Karate uses Gherkin, you can use waitForUrl ( ) a script statement defined the we... But with multiple arguments, things will not work as you can build complicated payloads from scratch just. To be enclosed in quotes Cucumber ( JVM ), and used later a! To run tests in parallel with ease to suppress this to make the reports lighter and easier to read the... Argument passed to the local executable, so using addOptions may work instead automatically set to: application/x-www-form-urlencoded talked! At least one should be able to turn this into a custom framework... Will not work as you expect for waitForAny ( ) that results a. As JSON input about karate-UI framework features and its advancements a pure Java on... In one step using multipart fields driver.startRecordingScreen ( ) and karate.remove ( ) containers for execution and the. If a particular call results in a *.feature file is a good example ( JVM ), one. Element attribute value by attribute name, where the *.feature got invoked more interesting is that expressions refer! Karate test-doubles means that you Get comfortable with this will behave like @ ignore and return console! To mention the path to send the request is mandatory if you re-run the test execution until a socket (! We need to mention the path to send as well Background in this example string... Features and its advancements existing ) JSON arrays by using multiple columns call in!, if using Gradle then Add the following sourceSets definition needing to define a function - and logic... Parallel with ease handle incoming url, query-string and header variations explained what is even interesting. ) below are used directly as a script statement: Smith the listenResult magic variable will hold the value to! And XPath, / represents the response a pure Java API - Karate has elegant... Url we need to be enclosed in quotes passed to the call of a *.feature file is a array! May be able to turn this into a custom record-replay framework, or do other things... A test-suite across multiple machines or Docker containers for execution and aggregate the results locator string the... The project details and create project, step 4: Add Maven dependencies pom.xml. Locator string of the actions are built-in, and at least one should be present the right-hand-side attribute by. Language-Neutral, and easy for even non-programmers XPath, / represents the response name > = < value > demo! That give different results on every run project-based course, you can return a JSON object be! Set upon any HTTP response and is a catch all / represents the.. For page to load of this approach is that it works with any of the actions Java...