Tutorial
#
OverviewIn this tutorial, we will test a simple web application using SICOPE Model: http://react-compare-app.surge.sh/
This application is very simple. It has these features:
- Add product
- Remove product
- Open cart
- Close cart
#
ModelTo test this application, we need to create models. There are 2 ways to create models:
- Models > Build
- Models > Import
info
We exported the model for you so you don't have to build it from scratch. All you need to do is download and import by the link below:
DownloadFor this web application, one model is enough:
- Label:
Fruits Store
- Tags:
fruits
,store
#
PlacesThis web application only have one page, so we can create one place called Home
#
HomeTo verify that we actually in home page, we can add a command to verify an element in it:
Command | Target | Value |
---|---|---|
Assert Element Present | css=.ProductList |
info
Everytime our model reach Home
place, it run this command to verify that we are actually in Home
web page.
#
TransitionsWe define transitions based on features this web application have:
- Add
- Remove
- Close Cart
- Open Cart
We also need one starting transition to tell this tool where to begin with:
- Go To Home
Usually those transitions are enough. But since we also want to choose random quantity, choose random product to add to cart, choose random product to remove from cart, we need at least 3 more transitions:
- Random Remove Product
- Random Add Product
- Random Quantity
info
We need to create extra transitions, because we don't want them to affect variables when reducing bug's reproduce steps
#
Go To HomeWe need these commands:
Command | Target | Value |
---|---|---|
Open | https://renaudtertrais.github.io/fruits-store/ | |
Store | 4 | added |
Store | closed | cart |
Store | removeProduct | |
Store | quantity | |
Store | addProduct |
There is no restriction to apply this transition, so the guard has value true
.
info
Each transition must come from at least 1 place to at least 1 place. There is one exception in this case: it is a starting transition, so it does not come from any place. There is only and only one starting transition in a model.
Unlike starting transition, all transitions below come from transition Home
to transition Home
.
#
AddWe need these commands:
Command | Target | Value |
---|---|---|
Type | xpath=//div[@class='ProductListItem__name' and text()='${addProduct}']/..//input | ${quantity} |
Click | xpath=//div[@class='ProductListItem__name' and text()='${addProduct}']/..//button | |
Assert Element Not Preset | xpath=//div[@class='ProductListItem__name' and text()='${addProduct}']/..//button[contains(@class, 'ProductListItem__add-to-cart-button')] | |
Execute Script | return ${added} + 1 | added |
Store | addProduct |
The condition to apply this transition is added < 8 && addProduct !== null && quantity !== null
, meaning:
- We have at least 1 product remaining to add
- We chose random product to add
- We chose random quantity
#
RemoveWe need these commands:
Command | Target | Value |
---|---|---|
Click | xpath=//div[@class='CartItem__name' and text()='${removeProduct}']/..//button | |
Assert Element Not Preset | xpath=//div[@class='CartItem__name' and text()='${removeProduct}']/..//button[contains(@class, 'CartItem__remove-button')] | |
Execute Script | return ${added} - 1 | added |
Store | removeProduct |
The condition to apply this transition is added > 0 && cart === 'open' && removeProduct !== null
, meaning:
- We added at least 1 product to the cart
- We chose random product to remove
- Cart is open
#
Open CartWe need these commands:
Command | Target | Value |
---|---|---|
Click | css=.App__cart-button | |
Store | open | cart |
The condition to apply this transition is cart === 'closed'
, meaning:
- Cart must be closed to be open
#
Close CartWe need these commands:
Command | Target | Value |
---|---|---|
Click | css=.App__cart-button.active | |
Store | closed | cart |
The condition to apply this transition is cart === 'open'
, meaning:
- Cart must be open to be closed
#
Random Remove ProductWe need these commands:
Command | Target | Value |
---|---|---|
Execute Script | var elements = document.querySelectorAll('.CartItem__remove-button'); var element = elements[Math.floor(Math.random() * elements.length)]; return element.parentElement.querySelector('.CartItem__name').textContent; | removeProduct |
The condition is added > 0 && cart === 'open'
, meaning:
- The cart is open
- At least 1 product is added to cart
#
Random Add ProductWe need these commands:
Command | Target | Value |
---|---|---|
Execute Script | var elements = document.querySelectorAll('.ProductListItem__add-to-cart'); var element = elements[Math.floor(Math.random() * elements.length)]; return element.parentElement.querySelector('.ProductListItem__name').textContent; | addProduct |
The condition is added < 8
, meaning:
- At least 1 product is not added to cart
#
Random QuantityWe need these commands:
Command | Target | Value |
---|---|---|
Execute Script | return Math.floor(Math.random() * 10); | quantity |
#
TaskNow, in order to test, we need to create a task and run it. Go to Tasks > Add New:
After creating a task, you will be redirected to tasks list page. Simply click on Run
action to run it.
info
When a bug is found, it will be notified to these channels if selected:
- Slack
#
BugYou can encounter a bug when you run the task for several times.
At first, the bug's steps can be very long like this:
But you can run Reduce
action to make it shorter after several tries.
Now it's time to take a look at the bug. The message is:
Unexpected element "xpath=//div[@class='ProductListItem__name' and text()='Ananas']/..//button[contains(@class, 'ProductListItem__add-to-cart-button')]" was found in page
It means when we set quantity to 0
, the Add to cart
button does not work as expected.
info
We can export the bug to Selenium IDE to verify:
caution
Type
command does not work well with Selenium IDE
#
SummarizeThat's it, we tested the Fruits Store
web application and found a bug using SICOPE Model tool.