diff --git a/README.md b/README.md index 16c2684..36b91cc 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,14 @@ robotframework/ │ │ ├── global_page.resource │ │ ├── home_page.resource │ │ ├── login_page.resource +│ │ ├── newProduct_page.resource +│ │ ├── newUser_page.resource │ │ └── store_page.resource │ └── variables/ │ └── global.resource └── tests/ + ├── admin/ + │ └── admin.robot ├── login/ │ └── login.robot └── store/ @@ -58,6 +62,9 @@ Python dependencies required to run the suite: drive the web UI. - `robotframework-requests` — RequestsLibrary, used by the API resources to call the ServeRest REST API. +- `Faker` — generates random user and product data (names, emails, + passwords, prices, descriptions) used by the tests, via `Evaluate` + calls in `global_page.resource`. ### `resources/variables/global.resource` @@ -69,23 +76,32 @@ Global variables shared across the whole project: - `${HEADLESS}` — whether the browser runs headless (`False` by default, so it opens visibly). -Also loads the `Browser` and `DebugLibrary` libraries, so any resource that -imports this file has access to them. +Also loads the `Browser` library, so any resource that imports this file has +access to it. ### `resources/pages/global_page.resource` -Shared setup/teardown keywords used by more than one test suite (login and -store), gluing together the API resource and the page objects to open the -browser and prepare/clean up test data: +Shared setup/teardown keywords used by more than one test suite (login, +store, and admin), gluing together the API resource and the page objects to +open the browser and prepare/clean up test data, plus helpers to generate +random test data via Faker (`pt_BR` locale): - **Keywords**: - `Open Login Page` — opens a new browser/context/page already on the login screen. - - `Prepare Login Test` — creates a valid user via the API and opens the - login page, leaving `${EMAIL}`, `${PASSWORD}`, and `${USER_ID}` + - `Prepare Login Test` — creates a valid (non-admin) user via the API and + opens the login page, leaving `${EMAIL}`, `${PASSWORD}`, and `${USER_ID}` available as test variables for the test and its teardown. + - `Prepare Admin Login Test` — same as above, but creates an admin user via + the API, for tests that need to reach the admin area. - `Cleanup Login Test` — closes the browser and removes, via the API, the user created in the setup. + - `Generate Random User` — returns a random name, email, and password + (via `Generate Random Password`), using Faker. + - `Generate Random Password` — generates a random alphanumeric password + (default length 10). + - `Generate Random Product` — returns a random product name, price, + description, and quantity, using Faker. ### `resources/pages/login_page.resource` @@ -103,16 +119,59 @@ Page object for the login screen (`${BASE_URL}/login`). Contains: ### `resources/pages/home_page.resource` -Page object for the customer home page (`${BASE_URL}/home`), shown after a -successful login. Contains: +Page object for the customer home page (`${BASE_URL}/home`) and the admin +home page (`${BASE_URL}/admin/home`), shown after a successful login. +Contains: -- **Locator**: `${LOGOUT_BUTTON}`. -- **Keyword**: +- **Locators**: `${LOGOUT_BUTTON}`, `${CREATE_USER_BUTTON}`, + `${LIST_USERS_BUTTON}`, `${USERS_TABLE}`, `${CREATE_PRODUCT_BUTTON}`, + `${LIST_PRODUCTS_BUTTON}`, `${PRODUCTS_TABLE}`. +- **Keywords**: - `Home Page Should Be Displayed` — confirms the user was redirected to the home page, by waiting for the logout button (visible only on this page) and checking the current URL. The wait is needed because the redirect happens client-side (SPA), asynchronously after clicking "Entrar". + - `Admin Page Should Be Displayed` — same idea, but asserts the URL is + `${BASE_URL}/admin/home`. + - `Click Cadastrar Button On Cadastro De Usuario Card` / `Click Listar + Button On Listar Usuarios Card` — open the "create user" / "list users" + admin cards. + - `Users Table Should Be Displayed` — confirms the users table is visible. + - `Click Cadastrar Button On Cadastrar Produtos Card` / `Click Listar + Button On Listar Produtos Card` — open the "create product" / "list + products" admin cards. + - `Products Table Should Be Displayed` — confirms the products table is + visible. + +### `resources/pages/newUser_page.resource` + +Page object for the admin's "create user" screen. Contains: + +- **Locators**: `${NEW_USER_NAME}`, `${NEW_USER_EMAIL}`, + `${NEW_USER_PASSWORD}`, `${NEW_USER_CADASTRAR_BUTTON}`. +- **Keywords**: + - `Input New Name` / `Input New Email` / `Input New Password` — fill in + the corresponding fields on the new user form. + - `Click Cadastrar Button` — submits the new user form. + - `User Should Be Created` — asserts the created user's email is visible + in the users table. + +### `resources/pages/newProduct_page.resource` + +Page object for the admin's "create product" screen. Contains: + +- **Locators**: `${NEW_PRODUCT_NAME}`, `${NEW_PRODUCT_PRICE}`, + `${NEW_PRODUCT_DESCRIPTION}`, `${NEW_PRODUCT_QUANTITY}`, + `${NEW_PRODUCT_CADASTRAR_BUTTON}`. +- **Keywords**: + - `Input New Product Name` / `Input New Product Price` / `Input New + Product Description` / `Input New Product Quantity` — fill in the + corresponding fields on the new product form. + - `Click Cadastrar Button on New Product Form` — submits the new product + form. + - `Product Should Be Created` — asserts the created product's name is + visible in the products table. ### `resources/pages/store_page.resource` @@ -143,6 +202,8 @@ through the UI: - `Create Standard User Via Api` — creates a standard (non-admin) user with a unique, randomly generated email, and returns the email, password, and id of the created user. +- `Create Admin User Via Api` — same as above, but creates the user with + `administrador=true`, so it can log in and reach the admin area. - `Delete User Via Api` — deletes the user (by id) created for the test, keeping the test environment clean. @@ -154,6 +215,7 @@ test and delete it afterwards, then drives the login page object to run scenarios such as: - Valid credentials redirect the user to the home page. +- An admin user's valid credentials redirect them to the admin page. - Invalid email and/or password show an "invalid credentials" message. - Blank email or blank password show the corresponding required-field message. @@ -180,6 +242,28 @@ style keywords used by the test cases (e.g. `the user adds the first item to the list`, `the user clears the list`), which simply delegate to the store page object keywords described above. +### `tests/admin/admin.robot` + +Test suite covering the admin area of the ServeRest front-end. It uses +`Test Setup`/`Test Teardown` to create a fresh admin user via the API, +log in, and land on the admin page before each test (delegating to +`Prepare Admin Login Test`), then drives the admin page objects to run +scenarios such as: + +- Creating a new user with randomly generated data (via `Generate Random + User`) and confirming it appears in the users table. +- Listing all users and confirming the users table is displayed. +- Creating a new product with randomly generated data (via `Generate + Random Product`) and confirming it appears in the products table. +- Listing all products and confirming the products table is displayed. + +The `*** Keywords ***` section of this file defines the Given/When/Then +style keywords used by the test cases (e.g. `the admin fills in the user +details with valid information`, `the admin clicks on the "Cadastrar" +button on the Cadastro de Usuário card`), which simply delegate to the +`newUser_page.resource` / `newProduct_page.resource` / `home_page.resource` +keywords described above. + ## Continuous Integration `.github/workflows/robot-tests.yml` runs the full suite on GitHub Actions: diff --git a/requirements.txt b/requirements.txt index 8820623..0536be4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ robotframework robotframework-browser robotframework-requests +Faker==26.0.0 \ No newline at end of file diff --git a/resources/api/users_api.resource b/resources/api/users_api.resource index a79cf88..00180d5 100644 --- a/resources/api/users_api.resource +++ b/resources/api/users_api.resource @@ -12,11 +12,9 @@ Create Standard User Via Api [Documentation] Creates, via API, a standard (non-admin) user with a ... unique email and returns the email, password, and id ... of the created user, to be used in the UI login test. - ${suffix}= Generate Random String 10 [LOWER][NUMBERS] - ${email}= Catenate SEPARATOR= usuario.teste. ${suffix} @qa.com.br - ${password}= Set Variable Teste@123 + ${name} ${email} ${password}= Generate Random User ${body}= Create Dictionary - ... nome=Usuario Teste + ... nome=${name} ... email=${email} ... password=${password} ... administrador=false @@ -24,6 +22,20 @@ Create Standard User Via Api ${user_id}= Set Variable ${response.json()}[_id] RETURN ${email} ${password} ${user_id} +Create Admin User Via Api + [Documentation] Creates, via API, an admin user with a + ... unique email and returns the email, password, and id + ... of the created user, to be used in the UI login test. + ${name} ${email} ${password}= Generate Random User + ${body}= Create Dictionary + ... nome=${name} + ... email=${email} + ... password=${password} + ... administrador=true + ${response}= POST ${API_BASE_URL}/usuarios json=${body} expected_status=201 + ${user_id}= Set Variable ${response.json()}[_id] + RETURN ${email} ${password} ${user_id} + Delete User Via Api [Documentation] Removes, via API, the user created for the test, keeping ... the environment's test data clean. diff --git a/resources/pages/global_page.resource b/resources/pages/global_page.resource index 8742dfb..d84e43e 100644 --- a/resources/pages/global_page.resource +++ b/resources/pages/global_page.resource @@ -1,5 +1,5 @@ *** Settings *** -Documentation Page object for the customer home page (${BASE_URL}/home). +Documentation Page object for common actions. Library Browser Resource ../variables/global.resource Resource ../../resources/api/users_api.resource @@ -23,7 +23,39 @@ Prepare Login Test Set Test Variable ${USER_ID} ${user_id} Open Login Page +Prepare Admin Login Test + [Documentation] Creates a valid user via API and opens the login page, + ... leaving email/password/id available for the test and teardown. + ${email} ${password} ${user_id}= Create Admin User Via Api + Set Test Variable ${EMAIL} ${email} + Set Test Variable ${PASSWORD} ${password} + Set Test Variable ${USER_ID} ${user_id} + Open Login Page + Cleanup Login Test [Documentation] Closes the browser and removes, via API, the user created in the setup. Close Browser Delete User Via Api ${USER_ID} + +Generate Random User + [Documentation] Return name, email and password using Faker (pt_BR) + ${fake}= Evaluate faker.Faker('pt_BR') modules=faker + ${name}= Evaluate $fake.name() + ${email}= Evaluate $fake.email() + ${password}= Generate Random Password + RETURN ${name} ${email} ${password} + +Generate Random Password + [Documentation] Generates a random password with a default length of 10 characters. + [Arguments] ${length}=10 + ${password}= Generate Random String ${length} [LOWER][UPPER][NUMBERS] + RETURN ${password} + +Generate Random Product + [Documentation] Return name, price, description and quantity using Faker (pt_BR) + ${fake}= Evaluate faker.Faker('pt_BR') modules=faker + ${productName}= Evaluate $fake.word() + ${price}= Evaluate $fake.random_number(digits=5, fix_len=True) + ${description}= Evaluate $fake.sentence() + ${quantity}= Evaluate $fake.random_number(digits=2, fix_len=True) + RETURN ${productName} ${price} ${description} ${quantity} \ No newline at end of file diff --git a/resources/pages/home_page.resource b/resources/pages/home_page.resource index a14d754..39a06c2 100644 --- a/resources/pages/home_page.resource +++ b/resources/pages/home_page.resource @@ -4,8 +4,13 @@ Resource ../variables/global.resource *** Variables *** -${LOGOUT_BUTTON} [data-testid="logout"] - +${LOGOUT_BUTTON} [data-testid="logout"] +${CREATE_USER_BUTTON} [data-testid="cadastrarUsuarios"] +${LIST_USERS_BUTTON} [data-testid="listarUsuarios"] +${USERS_TABLE} xpath=//table[contains(@class,'table-striped')] +${CREATE_PRODUCT_BUTTON} [data-testid="cadastrarProdutos"] +${LIST_PRODUCTS_BUTTON} [data-testid="listarProdutos"] +${PRODUCTS_TABLE} xpath=//table[contains(@class,'table-striped')] *** Keywords *** Home Page Should Be Displayed @@ -18,3 +23,42 @@ Home Page Should Be Displayed Wait For Elements State ${LOGOUT_BUTTON} visible ${current_url}= Get Url Should Be Equal As Strings ${current_url} ${BASE_URL}/home + +Admin Page Should Be Displayed + [Documentation] Confirms that the user was redirected to the admin + ... home page after login (URL and an element exclusive + ... to the admin page, such as the logout button, visible). + ... Waits for the logout button because the redirect + ... is done via SPA (client-side), asynchronously after + ... clicking "Entrar". + Wait For Elements State ${LOGOUT_BUTTON} visible + ${current_url}= Get Url + Should Be Equal As Strings ${current_url} ${BASE_URL}/admin/home + +Click Cadastrar Button On Cadastro De Usuario Card + [Documentation] Clicks the "Cadastrar" button on the "Cadastro de Usuario" + ... card, which is only visible to admin users. + Click ${CREATE_USER_BUTTON} + +Click Listar Button On Listar Usuarios Card + [Documentation] Clicks the "Listar" button on the "Listar Usuarios" + ... card, which is only visible to admin users. + Click ${LIST_USERS_BUTTON} + +Users Table Should Be Displayed + [Documentation] Confirms that the users table is displayed on the page. + Wait For Elements State ${USERS_TABLE} visible + +Click Cadastrar Button On Cadastrar Produtos Card + [Documentation] Clicks the "Cadastrar" button on the "Cadastrar Produtos" + ... card, which is only visible to admin users. + Click ${CREATE_PRODUCT_BUTTON} + +Click Listar Button On Listar Produtos Card + [Documentation] Clicks the "Listar" button on the "Listar Produtos" + ... card, which is only visible to admin users. + Click ${LIST_PRODUCTS_BUTTON} + +Products Table Should Be Displayed + [Documentation] Confirms that the products table is displayed on the page. + Wait For Elements State ${PRODUCTS_TABLE} visible \ No newline at end of file diff --git a/resources/pages/newProduct_page.resource b/resources/pages/newProduct_page.resource new file mode 100644 index 0000000..ce991da --- /dev/null +++ b/resources/pages/newProduct_page.resource @@ -0,0 +1,42 @@ +*** Settings *** +Documentation Page object for the admin create product page. +Resource ../variables/global.resource + +*** Variables *** +${NEW_PRODUCT_NAME} [data-testid="nome"] +${NEW_PRODUCT_PRICE} [data-testid="preco"] +${NEW_PRODUCT_DESCRIPTION} [data-testid="descricao"] +${NEW_PRODUCT_QUANTITY} [data-testid="quantity"] +${NEW_PRODUCT_CADASTRAR_BUTTON} [data-testid="cadastarProdutos"] + +*** Keywords *** +Input New Product Name + [Documentation] Fills in the name field on the new product registration form. + [Arguments] ${productName} + Fill Text ${NEW_PRODUCT_NAME} ${productName} + +Input New Product Price + [Documentation] Fills in the price field on the new product registration form. + [Arguments] ${price} + Fill Text ${NEW_PRODUCT_PRICE} ${price} + +Input New Product Description + [Documentation] Fills in the description field on the new product registration form. + [Arguments] ${description} + Fill Text ${NEW_PRODUCT_DESCRIPTION} ${description} + +Input New Product Quantity + [Documentation] Fills in the quantity field on the new product registration form. + [Arguments] ${quantity} + Fill Text ${NEW_PRODUCT_QUANTITY} ${quantity} + +Click Cadastrar Button on New Product Form + [Documentation] Clicks the "Cadastrar" button to submit the new product registration form. + Click ${NEW_PRODUCT_CADASTRAR_BUTTON} + +Product Should Be Created + [Documentation] Verifies that the new product has been created successfully. + [Arguments] ${productName} + ${locator}= Set Variable ${USERS_TABLE}//td[normalize-space(text())='${productName}'] + Wait For Elements State ${locator} visible timeout=10s + # Add verification steps here, such as checking for a success message or the presence of the new product in the product list. \ No newline at end of file diff --git a/resources/pages/newUser_page.resource b/resources/pages/newUser_page.resource new file mode 100644 index 0000000..6b1366b --- /dev/null +++ b/resources/pages/newUser_page.resource @@ -0,0 +1,36 @@ +*** Settings *** +Documentation Page object for the admin create user page. +Resource ../variables/global.resource + +*** Variables *** +${NEW_USER_NAME} [data-testid="nome"] +${NEW_USER_EMAIL} [data-testid="email"] +${NEW_USER_PASSWORD} [data-testid="password"] +${NEW_USER_CADASTRAR_BUTTON} [data-testid="cadastrarUsuario"] + +*** Keywords *** +Input New Name + [Documentation] Fills in the name field on the new user registration form. + [Arguments] ${name} + Fill Text ${NEW_USER_NAME} ${name} + +Input New Email + [Documentation] Fills in the email field on the new user registration form. + [Arguments] ${email} + Fill Text ${NEW_USER_EMAIL} ${email} + +Input New Password + [Documentation] Fills in the password field on the new user registration form. + [Arguments] ${password} + Fill Text ${NEW_USER_PASSWORD} ${password} + +Click Cadastrar Button + [Documentation] Clicks the "Cadastrar" button to submit the new user registration form. + Click ${NEW_USER_CADASTRAR_BUTTON} + +User Should Be Created + [Documentation] Confirms that the user was created successfully by + ... checking for a success message on the screen. + [Arguments] ${email} + ${locator}= Set Variable ${USERS_TABLE}//td[normalize-space(text())='${email}'] + Wait For Elements State ${locator} visible timeout=10s \ No newline at end of file diff --git a/resources/pages/store_page.resource b/resources/pages/store_page.resource index ee71386..3edcbff 100644 --- a/resources/pages/store_page.resource +++ b/resources/pages/store_page.resource @@ -1,5 +1,5 @@ *** Settings *** -Documentation Page object for the login screen (${BASE_URL}/login). +Documentation Page object for the store page. Resource ../variables/global.resource *** Variables *** @@ -41,6 +41,9 @@ Item Should Be Increased ${xpath}= Set Variable ... //div[@id='root']/div[@class='App']/div/div[@class='jumbotron']/div[@class='container-fluid']/div/section[@class='row espacamento']/div[@class='card col-3'][1]/div[@class='card-body']/div[@class='row']/div[@class='col-3'][2]/p Wait For Elements State xpath=${xpath} visible timeout=10s + ${quantity_txt}= Get Text xpath=${xpath} + ${quantity}= Convert To Integer ${quantity_txt} + Should be True ${quantity} > 1 msg=Expected quantity to be greater than 1, but got ${quantity}. List Should Be Empty [Documentation] Verifies that the shopping list is empty. diff --git a/tests/admin/admin.robot b/tests/admin/admin.robot new file mode 100644 index 0000000..2291e8e --- /dev/null +++ b/tests/admin/admin.robot @@ -0,0 +1,110 @@ +*** Settings *** +Resource ../../resources/variables/global.resource +Resource ../../resources/pages/global_page.resource +Resource ../../resources/pages/login_page.resource +Resource ../../resources/pages/home_page.resource +Resource ../../resources/pages/newUser_page.resource +Resource ../../resources/pages/newProduct_page.resource +Test Setup Open Browser To Admin Page +Test Teardown Cleanup Login Test + +*** Test Cases *** +Admin Wants To Create a New User + [Documentation] This test case verifies that an admin can create a new user. + [Tags] admin smoke + ${name} ${email} ${password}= Generate Random User + Given the admin wants to create a new user + When the admin clicks on the "Cadastrar" button on the Cadastro de Usuário card + And the admin fills in the user details with valid information ${name} ${email} ${password} + And the admin clicks on the "Cadastrar" button to submit the form + Then the new user should be created successfully + +Admin Wants To See The List Of Users + [Documentation] This test case verifies that an admin can see the list of users. + [Tags] admin smoke + Given the admin wants to see the list of users + When the admin clicks on the "Listar" button on the Listar Usuários card + Then the list of users should be displayed + +Admin Wants To Create A New Product + [Documentation] This test case verifies that an admin can create a new product. + [Tags] admin smoke + ${productName} ${price} ${description} ${quantity}= Generate Random Product + Given the admin wants to create a new product + When the admin clicks on the "Cadastrar" button on the Cadastrar Produtos card + And the admin fills in the product details with valid information ${productName} ${price} ${description} ${quantity} + And the admin clicks on the "Cadastrar" button to submit the product form + Then the new product should be created successfully ${productName} + +Admin Wants To List All Products + [Documentation] This test case verifies that an admin can see the list of products. + [Tags] admin smoke + Given the admin wants to see the list of products + When the admin clicks on the "Listar" button on the Listar Produtos card + Then the list of products should be displayed + +*** Keywords *** +Open Browser To Admin Page + [Documentation] Opens the browser and navigates to the admin page. + Prepare Admin Login Test + Input Email ${email} + Input Password ${password} + Click Entrar Button + Admin Page Should Be Displayed + +the admin wants to create a new user + No Operation + +the admin clicks on the "Cadastrar" button on the Cadastro de Usuário card + Click Cadastrar Button On Cadastro De Usuario Card + +the admin fills in the user details with valid information + [Arguments] ${name} ${email} ${password} + Input New Name ${name} + Input New Email ${email} + Input New Password ${password} + + +the admin clicks on the "Cadastrar" button to submit the form + Click Cadastrar Button + +the new user should be created successfully + User Should Be Created ${email} + +the admin wants to see the list of users + No Operation + +the admin clicks on the "Listar" button on the Listar Usuários card + Click Listar Button On Listar Usuarios Card + +Then the list of users should be displayed + Users Table Should Be Displayed + +the admin wants to create a new product + No Operation + +the admin clicks on the "Cadastrar" button on the Cadastrar Produtos card + Click Cadastrar Button On Cadastrar Produtos Card + +the admin fills in the product details with valid information + [Arguments] ${productName} ${price} ${description} ${quantity} + Input New Product Name ${productName} + Input New Product Price ${price} + Input New Product Description ${description} + Input New Product Quantity ${quantity} + +the admin clicks on the "Cadastrar" button to submit the product form + Click Cadastrar Button on New Product Form + +the new product should be created successfully + [Arguments] ${productName} + Product Should Be Created ${productName} + +the admin wants to see the list of products + No Operation + +the admin clicks on the "Listar" button on the Listar Produtos card + Click Listar Button On Listar Produtos Card + +Then the list of products should be displayed + Products Table Should Be Displayed \ No newline at end of file diff --git a/tests/login/login.robot b/tests/login/login.robot index ea24f41..58f0932 100644 --- a/tests/login/login.robot +++ b/tests/login/login.robot @@ -20,6 +20,13 @@ User With Valid Credentials Should Be Redirected To The Home And clicks on Entrar Then this user must be redirected to the home page +Admin Can Access Admin Page + [Documentation] This test case verifies that an admin user can access the admin page. + [Tags] admin smoke + Given the admin user wants to access the admin page + When this admin user types the email and password + Then the admin page should be displayed + User With Invalid Email Should See Error Message [Documentation] A user who enters an invalid email and/or password and clicks ... "Entrar" must see a message informing that the @@ -92,3 +99,14 @@ this user must be redirected to the home page the message "${message}" must appear Login Error Message Should Be ${message} + +the admin user wants to access the admin page + Prepare Admin Login Test + +this admin user types the email and password + Input Email ${email} + Input Password ${password} + Click Entrar Button + +the admin page should be displayed + Admin Page Should Be Displayed \ No newline at end of file