Where exactly the data-cy or data-test-id attribute to the element to test can be added? - cypress

I am a beginner for the Cypress automation testing. I have gone through the good practice document for Cypress E2E where it suggests to use data-cy or data-test-id for element selection. This might be a simple and dumb question but I am really curious to know the answer from you guys. I tried googling but no luck.
Where exactly the data-cy or data-test-id attribute to the element to test can be added?
a. Do I have to checkout the code from the developers team, then add the attribute in there?
b. Can I use the invoke command in cypress (just like we can add/remove attr using invoke in jquery)?
c. Any other method?
If the option a. is your answer, then
what are the steps you follow?
Does the app code and testing code need to be in one project?
What hierarchy of element selection you follow?
(More info: I have frontend in Typescript and React, backend in sql, test project in cypress)

If data-cy or data-test-id attributes are not added to the elements in your project, you can not access the elements using these attributes.
Basically, it is a decision that team should take while developing front end application that all testable elements should have proper data-cy or data-test-id which gives more information about the element and it makes easy to write more stable and readable tests.
So I would suggest to discuss within a team to define strategy to add these attributes to the existing code and new code.
Read more about it at best practices for selecting elements in cypress

Related

AutoIT Page/Window Object Model

I would like to ask if we can also achieved a Page/Window Object Model in AutoIT? Majority of my project assignment was on Web Automation and I'm using Selenium Webdriver with Framework uses Page Object Model. Currently, I'm assigned to a project for GUI automation. I like to implement this kind of approach also in AutoIT if feasible so that I can reuse the objects to other classes. We are planning to use AutoIT standalone. I noticed that most of the example available in the internet was the object created on each class/script.
Your insights are highly appreciated.
Thanks!
General:
That common approach of using the Page Object Model (POM) Design Pattern isn't quit good feasible with AutoIt. Of course you can create a object structure with AutoIt too, but it was not intended for the language. Anyway, some of the goals of POM can be achieved with the following example suggestion of a test structure.
Please notice:
Since you don't provide enough information about your application under test (AUT), I explain a basic structure. The implementation depends on your application (SWING/RCP, WinForm etc.). It's also important which tool support do you need for your page object recognition. Besides WinForm that could be controled by ControlCommand functions in AutoIt, it's a proper way to use UIASpy or au3_uiautomation as helper tools.
UIASpy - UI Automation Spy Tool
au3_uiautomation
It's an advantage to know the POM structure in context with Selenium. I usually include a test case description with behavior driven development BDD (Gherkin syntax with Cucumber or SpecFlow), but this will not be a part of that example here.
Example structure:
The structure consists of two applications under test Calc and VlcPlayer. Both follow the common structure PageObjects and Tests. You should try to devide your page objects (files) in many subfolders to keep an overview. This substructure should be similar for the Tests folder/subfolders.
In the Tests area you could include several test stages or test categories depending on your test goals (Acceptance/UI tests, just functional smoke tests and so on). It's also a good idea to control the execution order by an separat wrapper file, TestCaseExecutionOrder.au3. This should exist for all test categories to avoid a mixing of them.
This wrapper au3 file contains the function calls, it's the processing start/control.
Approach description:
TestCaseExecutionOrder.au3
Calls the functions which are the test cases in the subfolders (Menu, PlaylistContentArea, SideNavigation).
Test case NiceName consists of some test steps.
These test steps have to be included into that script/file by:
#include-once ; this line is optional
#include "Menu\OpenFolder.au3"
Test step OpenFolder.au3 (which is a part of a test case) contains the function(s) to do the folder loading and there content.
In that functions the PageObject MenuItemMedia.au3 will be loaded/included into the script/file by:
#include-once ; this line is optional
#include "..\..\..\PageObjects\Menu\MenuItemMedia.au3"
File MenuItemMedia.au3 should only contain the recognition mechanism for that area and actions.
This could be find menu item Media (as a function).
or find open folder menu item (as a function) and so on.
Func _findMenuItemMedia()
; do the recognition action
; ...
Return $oMenuItem
EndFunc
In the test step OpenFolder.au3 which calls _findMenuItemMedia() like:
Global $oMedia = _findMenuItemMedia()
can a .click executed or something like .getText etc.
The test cases should only #include the files which are necessary (test steps). The test steps should also only #include the necessary files (page objects) and so on. So it's possible to adjust the recognition functions once and it can be used in the corresponding test steps.
Conclusion:
Of course it's hard to explain it in this way, but with this approach you can do a similar way like in Selenium for web testing. Please notice that you properbly have to use Global variables often. You have to be ensure the correct includings and don't lose the overview of your test, which is in OOP test based approaches much easier.
I recommend the usage of VS Code, because you can jump from file to file at the #include statements. That's pretty handy.
I hope this will help you.

Is there any benefit of defining radio buttons in a Page Object model (eg. SitePrism) rather than using Capybara directly?

I was using a cucumber/ruby/capybara/siteprism framework and implementing the test pages at present. I've reached a point where there are a lot of radio buttons (over 20) per page in several pages, and I was thinking if there's really any benefit in trying to map all those as static elements in my page object model?
Ie, thinking about it, it seems much more convenient to just use the text of the radio button in the step definition and call the capybara 'choose' method directly, something like the following, so that I don't need to do anything else for those 20+ radio buttons, it should all just work by changing the parameter we're passing in the feature:
cucumber feature:
When I select that "I am over 18"
capybara step:
When /^I select that "(.*)"$/ |option|
choose(option)
Whereas with a page object model like siteprism, I guess the implementation would need to define and maintain all those elements independently in a format similar to:
element :over_18_button, :radio_button, "I am over 18"
element :over_12_button, :radio_button, "I am over 12"
etc x50times
And for using it, one should create the page, call the element, which doesn't seem as straight forward to me?
siteprism step:
When /^I select that "(.*)"$/ |option|
case option
when 'I am over 18'
over_18_button.click
when 'I am over 12'
over_12_button.click
I guess one could create 'elements' or a 'section' with an array to all the buttons, but then, we'll have to put extra logic to parse them and click on the relevant one anyway somewhere in the code, whilst it would be all done neatly and without the need for any extra code or maintenance with the 'choose' method from capybara.
Am I right to assume that in this example using Capybara is a better option?
or if it'd be better to define 'ALL' web elements in the page object model, what would the benefit of that be? and could the page object code be done in a different way to take advantage of any possible benefit?
That complicated case statement is unnecessary.
When /^I select that I am over "(\d\d)"$/ |age|
#page_object.select_age(age)
I'm not familiar with site_prism. My watir_drops gem would let you define everything with the same pattern like this:
element(:age_button) { |age| browser.radio_button(text: "I am over #{age}")
with this method in the page object:
def select_age(age)
age_button(age).set
end
We could also get into a whole long discussion on using declarative instead of imperative steps. Also, best practice Page Object usage avoids directly calling defined elements. Call methods that accomplish the business logic and those methods do all the implementation including element definitions and actions on them.
Old question but adding important missing info
The way in which site_prism works allows you to define your selector using anything that can be queried in Capybara. So if you want to define your radio using the text, you can do that. Or any other locating strategy you want to use.
Obviously traditionally I would advise using css locators (
element :my_radio, text: 'foo'), because they're easiest to debug and re-use. Furthermore the OP advised he had 50+ of these. If they were identical, they could be abstracted out into a Helper Module or he could even meta-program them in using a loop and index (If they followed a simple index_naming_pattern)

Using Page Objects vs Config Files in Selenium

I've been using Ruby Selenium-Webdriver for one of the automation scripts I'm developing and I'm being asked to use Page Objects, we use page objects a lot however for this application I am using CSV file instead, I have defined all the xpaths that I'm using in my application in a CSV file and I'm parsing that CSV file in my script to refer to those objects, I would like to know is there much of a difference in using a class for defining Page Objects or using a CSV file instead apart from performance concern? I believe using a CSV file will be an addon for us from configuration standpoint and will make it much easier to maintain, any suggestions on this?
Edit - In our use case, we're actually automating applications built on a cloud based tool, so basically all the applications share same design structure from HTML standpoint so we define xpath patterns in CSV and then we pass certain parameters to some custom methods that we've developed to generate xpath's automatically using the CSV instead of finding those manually as its overhead for us because we already know that all the applications will share similar xpath pattern for all elements.
Thanks
I think, POM is better than CSV approach. In POM, you put elements for a page in a separate class file. So, if any change is to make then it's easier to find where to change/maintain. Moreover, it won't get too messy as CSV file and you don't need to use extra utility function to parse those.
There is also a pageobjects gem that provides a set of libraries over and above webdriver/watir, simplifying the code.
Plus, why xpaths? Its one of the last recommended ways to identify an element.
As for the frameork aspect, csv should be more of a maintenance problem than PageObjects. Its the basic difference between text and code. You enforce Object oriented approach on your elements in PageObjects but that is not possible with csv.
In the best case scenario, you have created a column/separate sheets defining which page that element xpath belongs to. That sounds like an overhead. As your application / suite grows there can be thousands of elements. Imagine parsing/ manually updating a csv with that kind of data.
Instead in PageObjects, your elements will be restricted to the Page. Any changes to the app will also specify which elements may get impacted. Now, when define your element as an object in PageObject, rather than css, you also dont need to explicitly create your elements by reading the csv.
It completely depends on the application and the type of test you might perform.
Since it is an automated test script, you do not have to really worry about the performance of the script (it might take few more milli seconds to parse, which should be OK).
Maintaining all the elements identification properties & corresponding actions in a CSV file will make the maintenance easier and make the framework application independent which are nice. But maintaining your framework is bit difficult to make it more robust. Both approaches have its own pros and cons.
Refer to below posts [examples are in java - but you will get the idea]:
Keyword driven framework
Advanced Page Objects
Update:
If you like both, you can comeup with your implementation to easily integrate these too.
#ObjectRepository(src="/login.csv")
public class LoginPage{
private Map<String, WebElement> elements;
public void login(){
elements.get("username").sendKeys('');
elements.get("password").sendKeys('');
elements.get("signin").click();
}
}
Ie, define all the elements in a config file like csv/json etc. Let the page object refer to the class for the page elements. All the methods will be part of the page class.

How much rework do i have to do when moving from simple automation to Page Object Model framework using Cucumber and Selenium/Capybara?

My Goal is to create a Page Object Model Automation framework using Cucumber with capybara/selenium for mu client project. Currently my knowledge related to Page Object Model gem is very limited and at the same time i want to show some delivery by creating automation scripts using cucumber and capybara. So i am in the process of creating some feature files and subsequent step definitions.
So my question is, If i move to simple automation to POM framework, how much rework i have to do in terms of scripts and also if this approach is correct. Please guide me as i am pretty new to ruby automation.
Well this can be a very opinionated question, but I'll try to keep it simple:
If you already have well structured and modularised code (cucumber features and step defs), it won't take significant changes to move to POM. Its essentially a different structuring technique to keep your code organised and keep your changes minimal/confined.
Gems like siteprism can help you with creating well structured page objects, if you are open to learn an additional DSL (for siteprism) on top of cucumber / capybara. Or you can roll out your own without any additional libraries, though it would demand a thorough understanding of POM architecture and best practices.
Hope that helps.
I believe you will have a little work to migrate and meet increasingly the tool, the Framework POM only shows speed gain when you have some pages that already are mapped, it might take some time to be shown in reports, but I believe it has much to gain, organization, clarity and speed are some of the advantages of migration.
In my work I help other QAs learning and use POM in one day, a lot of guys use xpath to find objects, I just show how they can reuse that xpaths in a page object.
The second step I show to use method, not only elements, then they can reuse a lot of code and stop repeat steps, find where they break and use a simple method in siteprism page, example:
element :field_login , :xpath, "login"
element :field_password, :xpath, "password"
element :login_button, :xpath, "login_button"
def authenticate (username, password)
field_login.set username
field.password.set password
LoginPage.new if login_button.click
end
My next step is show to leave to use xpath and use css elements.
And after some sprints, they understand the beneficts of the framework, and it is default for all automation, include the DEVs can understand and help in tests now.
Warning this answer is somewhat controversial.
I'd say don't bother using the Page Object Model, its fundamentally flawed. The web is about resources and representations (REST) not about pages. BDD is about behaviour, not pages.
The danger with POM (particularly when you are not experienced) is that you write lots of scenarios to test what is on each page. When really what you should be doing is writing scenarios that confirm that some behaviour exists.

How can identify element by using UIAutomatorviewer for mobile native app when we don't any unique attribute of the element

I am beginner in mobile automation testing and I want to learn how to identify element uniquely when element don't have any unique attribute.
The simples answer is "you can't". You have to identify it to the best of your capabilities.
If you previously know the app you are testing (most people are making tests specific for one app) then you can use the index property to your advantage.
If you don't you can only do an heuristic with as many properties you know about the object you are trying to identify.
Check uiAutomatorViewer (in sdk-folder/tools) to see the layout currently visible on your screen (UiAutomator sees exaclty the same).
Check UiObject and UiSelector classed to see which properties you can access.
If you have any more specific questions just say it :)

Resources