Documentation

Welcome to the Hexo documentation. If you encounter any problems when using Hexo, have a look at the troubleshooting guide, raise an issue on GitHub or start a topic on the Google Group.

How to Prepare Environment For Bluestone

  • Install Nodejs LTS from website: https://nodejs.org/en/
  • Install GitHub from from: https://git-scm.com/downloads
  • Install Bluestone from cmd command prompt: npm install bluestone@latest -g
  • Launch cmd as administrator and run following command bluestone install
  • Close administrator cmd
  • Clone Sample Project from Git: git clone https://github.com/3wweiweiwu/sample-bluestone-project.git
  • Install prerequisite for automation code. Go to sample project in command line prompt and install prerequisite: npm install
  • Launch bluestone server by running command in command prompt: bluestone start .
  • You are ready to go!

What is Typical Process of recording workflow

Overall Step

Create UI automation is easy, here is general breakdown

  • Launch Bluestone
  • Record Steps and Add Validation
  • Correlate Locator when recording is done
  • Test Run your script
  • Output Script

Launch bluestone.

  1. Launch Bluestone Service

    1. In a command prompt, run command: bluestone start "path to your automation project"
  2. Start recording

    1. In a seperate command prompt, run command bluestone record "your url"
  3. Status Check

    1. if there is purple rectangle when you hover your mouse over different elements. You may refresh web browser. Bluestone shall load automatically.

Record Your Step and add validation

  1. Run your workflow.

    1. For complicated web page, I would recommend to do so at rate of 1 operation/second
  2. Add a validation (Pause Record)

    1. Press Alt+q combo key to call bluestone tab
    2. In spot (1), select your intention. In this case, select “verify”
    3. In spot (2), select specific step you would like to take. In this case, select “element exists”
    4. In spot (3), type in waiting time, please make sure it is greater than 1s
    5. In spot (4), run step to verify you work
    6. If everything looks good, click spot(5) to add this to the workflow steps
    7. If you want to resume your recording, click spot (6)
      \
  3. Correlate Locator when recording is done

    1. Press Alt+q combo key to call bluestone tab

    2. Go to workflow panel. In the panel, choose workflow (spot 1)

    3. Specify test suite name and test case name.

      1. Please note that, testcase name will be used as file name as well. PLease make sure it does not contain illegal characters (spot 2 and 3)
    4. Correlate Locator by clicking “Resolve Pending Issue” button (spot 4)

    5. You expect to see message in the note bar(spot 5) about your action item. Most likely, you will be asked to correlate locator

    6. Go to particular step and click “Edit Locator” Button

    7. In the Locator Definer view, enter locator name (spot 1) and locator (spot 2). bluestone support both selector and xpath. Otherwise, you can click “Revert” button to use default locator. You can click on “Confirm” button once you are done

      1. On the right side, you expect to see the view where this particular step is taken. Html is incorrect, you can use Previous html or Next html button to navigate through
      2. If you want to override existing locator with what you provide, you can use “force override” button
    8. Repeat 4,5,6,7 until you correlate all locators. You expect to see text like

      1. Please note that Bluestone will automatically correlate existing locator in its library
  4. At this point, you can click on “Run Workflow Button” to test run your script.

  5. Output script. Click “Create Testcase Button” to output your script

How to Run and debug Puppeter Scripts

Run all script via command line

  1. Launch command prompt
  2. go to automation project root folder
  3. Run following command: npm start

Run particular testcase via commnd line

  1. Launch command prompt
  2. go to automation project root folder
  3. Run following command: node ./node_modules/mocha/bin/_mocha ./script/*.js --exit true --grep "^test1 test2$" --timeout 60000s
    1. –timeout the maximum timeout for each test case execution
    2. ^test1 test2$, the test suite and test case name. It supports regular expression

Configure Runtime in vscode

  1. Install Vscode Extension: “Mocha sidebar”

  2. Go to setting menu

  3. In setting, search keyword “mocha”

  4. Go to Mocha>Files: Glob.

  5. Change pattern to “test/**/*.js”

  6. Go to testing tab in vscode and click refresh key, it should find your script autoamtically

  7. Go to any test file, you can debug the testcase

  8. Depends on the length of your test, you may need to update timeout

Locator Function Introduction

If you have worked with Bluestone, you will be familiar with the button “Revert Selector”, this button helps us to automatically generate the locator for a Web Element that we selected previously

The functionality of “Revert Selector” button is provided by “bluestone-selector-gen.js” class and this class is made up for “Locator Functions”

Each Locator Function is created for a specific web-element, the objective is identifying some HTML elements in a specific structure that appear only in this web-element and then with these same HTML elements Bluestone is going to create the locator

Structure of bluestone-selector-gen.js

The main function is “getLocator” this function call to the rest of the locators functions, in the first line of “getLocator” you can see the const “functionList” in this list are the locators function, once the “getLocator” function is called Bluestone is going to execute the first locator function in the list, if this first locator function doesn’t generate a locator that we can use Bluestone is going to call the next function, if any locator function works the “getLocator” is going to return an object with null elements


Creating a Locator Function

First, we need to create manually a Locator, please see Create-locator-generator manual, this locator manually created is going to give us a reference of what we want to generate

All the locator functions have one and only one parameter and this parameter represent the web-element which we are working (the web-element that we selected when we press ctrl+q in the Bluestone UI), in this example we are calling the parameter like element

Now you must ask if the web-element has the specific properties that identify it as the element for which the function was created

For example, you can ask if the element has a specific tag

Also, you can ask if the element has a specific attribute and if this attribute is equal to a value or a set of values

Please see the previous two examples and analyze what happened when the element does not have the tag or the attribute that we are searching for

How you can see when the tag or the attribute do not match, we return the function createOutput without arguments, when the functions return that the code go to the next locator function

Use parentElement method

Sometimes we also need to know the properties of parent’s element for that we have the method parentElement

Its syntaxis is

parent = element.parentElement

The result of this is that the variable parent is going to be the web-element which child is the element

Use getParentNode function

In some cases, we need find a specific parent of an element, for that we have the getParentNode

The following example can read like “Give me the first element’s parent which has tag like TR, if there is not any parent with that specification (if the result of *getParentNode is null) return the function createOutput without arguments”

Use childNodes method

The childNodes method is the opposite of parentElement method, its function is getting all the element’s sons

Its sintaxis is

let childs = element.childNodes

The result of this is that the variable childs is going to be an array, and each element of the array will be a web-element which parent is the element

Use getElementByXpath function

Ok, now we know how to get all the elements that we need to create our locator but how do you know that the locator works and not only that, if works, how can we know if the locator only works for our specific web-element and no other. For this we have the getElementByXpath function

Its sintaxis is

let elements = getElementByXpath(locator)

The result of this is that the variable elements is going to be an array, and each element of the array will be a web-element that match with our locator
, once we have the result of the getElementByXpath function only need to ask how many elements have the array, if number of elements are 0 then the locator does not work, if number of elements are more than 1 then the locator works for several web-elements, therefore the locator only works if the length of the array is equal to 1

A final locator function looks like that

Please note that in the final line we return the createOutput with element and locator like parameters

What is customized function and why do we need that

In several cases we need to prepare the environment before of reproduce a test cases, for example, assume that in the test case we need to create an element so we use Bluestone to automate the creation of this element, if we don’t prepare the environment each time that the script run is going to try to create the same element with the same name and properties this could be a problem because in the most cases the site don’t allow have two elements with the same name, so before of create a new element we need to delete the old one

To help the final user to prepare the environment we can create a customized function, so before of start to recording the user will be able to call the function to delete the element with the same name and this function will be recorded already in the script

How to add customized function

To create a new customized function, we need to open a new terminal initialize bluestone with the command:

bluestone start .\

In another terminal we run the command:

bluestone function . FunctionName

Replacing FuntionName for the name of the function

Bluestone should automatically add the line FunctionName: new FunctionName.FunctionName() to the bluestone-func.js file and create the FunctionName.js file, this file is going to be the template where we are going to create our function

We can say taht the FunctionName.js file is divided into three parts the constructor, the async function and the API functions

Constructor

In the constructor we can specify the locators that indicate to Bluestone when can display the customized function, for this we have to specify all the relevant locators in its respective area

Async Function

To get a better understanding we are going to call this function as Main Async Function, in this area we put the code that we want Bluestone execute when we call the function also we specify the parameters that Bluestone ask to the final user, for example, in the previous case where we need to clean the work space deleting some elements Bluestone use API requests and since all the sites have some level of security we need to request the user that indicate the user name and password for access to the site, also since the URL could change the time in time we will need the basic URL of the requests, probably also need to indicate the element’s name that bluestone is going to delete

When we create the template of the function the Async Function looks like this

If we must implement the previous example, we need to change the default variables for the variables that we need (URL, username, password, and element’s name), please note that the change is in two parts (See the elements marked in yellow), after of the declaration of variables we put a little description that the user can read (See the elements marked in pink)


Also, in the top of all configurations we put a name of the function that the user can recognize (See the elements marked in red)

With the previous configuration the user should see this in th UI:

How you can see all that you define in the code is going to be reflected in the UI

Sample Customized Function to Prepare Environment via RestApi

The next step is creating the instructions that we want Bluestone to do when the function is called

For “best practice” we are going to create API Functions outside of our Customized Function and those functions are going to be called in the Main Async Function, is very important that we call API Functions inside of the try of the Main Async Function, something like this:

How you can see, we called two API Functions “getAllCatchReports” and “deleteCatchReportForId”, we called API Functions because they are created using the API requests. The first is called to get some ids and the other is used to delete the elements that correspond to those ids

Creating an API Function using requests

Ok, now you know how the Customized Function is structured but…. What is inside of the API Functions?

Before answering that we need to understand some basic concepts

  1. API Calls or Requests

Is the process of a client application submitting a request to an API and that API retrieving the requested data from the external server or program and delivering it back to the client

Each time that the client require get information of the API or need that the API modify something use an API Call and when the API receive and API Call the API is going to send a Request to the client

  1. Request Method

A method indicates what is the basic purpose of the request. There are 4 types of methods: GET, POST, PUT and DELETE, in this moment we do not need to understand what the difference between them is, we only need know that each request has one

  1. URL’s request

Is the most essential element in the request, the URL’s request indicates to the API which are the actions needed to execute the request

  1. Header

In the header we can see a lot of information but the most important is the URL’s request and the method

  1. Payload

It is the crucial information that the client submits to the API when the client are making an API request, normally is sending with methods POST or PUT

  1. API key or access token

The API needs to know if the request is being sent to an authorized user

There are 2 ways to do it the first is sending the credentials (user, password and sometimes domain) and the second is with the access token, to get the access token we need to send a request with the credentials and then the API should respond us with an access token, this access token is going to be send it with the request

  1. Response

When the API receives a request, it is going to send a response, the response is sent in JASON format and has information of success or failure and in some cases also has information that the client needs to show the information

Obtain the request needed

To get the requests that the client sends to the API please follow the next steps

  1. Open a web browser in incognito view

  2. In any part of the window press right click and select “Inspect”

  3. Go to “Network” and select the checkboxes “Preserve log” and “Disable cache” the window should look like this

  4. Now all the requests that the client send its going to be recording after some actions in the web server the windows is going to looks like this

  5. Select any of the requests and the web browser is going to display the information of this request

  6. There is not an easy way to identify the request that we need but you can see the following suggestions

  • Before of make the action in the web browser you can clear the recording, if you do that when you make the action the only request that is going to display are those which are relates with the actions, for example supposed that when you press a button the web browser display a list of elements so before of press the button you can clear the recording and then press the button, so when you look for the request which response has the information that you need is going to be easier

  • When you look for a request that asks for information start with the request which method is a GET or POST

  • It is difficult to read a response because it is in JASON format so you can use a JSON Viewer like this tool, we can copy/paste the response in the text area and the tool will show us the information in an uncomplicated way to understand, plese see the images below

  • If we need a request to delete elements, the request has the method DELETE

Identify the access

As we saw earlier there are two ways to demonstrate to sever that we are authorized people

The first way with Access Token, when the request has an Authorization section like the image below means that the request uses an Access Token otherwise the request needs to send the user’s name and password

Create our API Function

Create our API Function using the Token
  1. We need to create a function that use the request to access to the site, for example when we want to access a site and the site ask us a user and password the request to access is going to be sending when we press the button of login, we can identify this request because its response should include the Access Token like this:

In this case we do not need use the JASON Viewer tool because in FireFox the response is already converted in a straightforward way to see

  1. Once we identify the request of Login, we can extract the URL and create the authenticate function. Please note that the user, password, and part of the URL are sending like parameters because the final user is going to indicated

  2. Now we are going to create our API Function taking the URL’s request, please remember that part of the URL is indicated for the final user, so we are going to get like a parameter

  3. After creating the URL’s request we are going to get the Access Token with our Authenticate Function

  4. With the URL’s request and the Access Token we are going to create the variable res and store the response of the request that uses the URL and the Access Token

  5. Finally we are going to manipulate the information of the response to get the element/s that we need

Create our API Function using API Access
  1. Now we are going to create our API Function taking the URL’s request, please remember that part of the URL is indicated for the final user, so we are going to get like a parameter

  2. Specify the method

  3. Specify the data, in the data we are going to indicate the information of the Payload

  4. We include in the beginning of function the variable credentials with the user and password, this is because the request of the example does not use an Access Token

  5. Finally we are going to manipulate the information of the response to get the element/s that we need

How to update customized function

Sometimes there is a product change and with this the request taht we use could also change

In that case first we need to identify where the problem is

To identify it we can put Debugger Points in the API Functions specifically in the catch areas and then run manually a test case which is calling the Customized Function, with this we can know in which API Function is the problem

Once we identify which is the API Function that we need to fix we are going to record again the request that the site uses to make the action and we will compare, if there is something different, we only need no replace it