Can we organize an Object Repository with parent object?

Hi,

I would like to know if is possible to organize the Object Repository with parent object and child objects.

For example, I have a page, in this page, I would like to have a parent object which is identify by a XPath, and in this parent object, I would like to have child’s objects.

Thanks for your help.

1 Like

@Christophe said:
Hi,

I would like to know if is possible to organize the Object Repository with parent object and child objects.

For example, I have a page, in this page, I would like to have a parent object which is identify by a XPath, and in this parent object, I would like to have child’s objects.

Thanks for your help.

Hi Christophe,

Object Repository in Katalon Studio is structured based on POM design. Each web page in the AUT will have correspondent test objects. To address your question, Katalon Studio doesn’t support reorganize objects within objects.

May I ask what are you trying to achieve? Please help to provide details information so that Katalon team better understand your issue and might able to find a workaround.

Thank you for using Katalon Studio,
Liam

Hi Liam,

Thanks for your answer.
I used to use Ranorex which is similar to Katalon Studio.

In Ranorex, we can organize the Object Repository with root folder which is identify by a xpath. In this root folder, we can have child objects.

In this way, we can organize the structure of the Object Repository. I hope this is more clear.

I’m having this issue too in Katalon, but did with Protractor successfully. There i had page objects which build a hierarchy.
Basically its about redundancy.

An Example-dom:

- id:whatEverFrame
- - id:ButtonOK
- - id:ButtonCancle

xpath in Katalon:

/whatEverFrame/ButtonOK
/whatEverFrame/ButtonCancle

Code in Protractor:

function getwhatEverFrame() {
    return element(by.css('#whatEverFrame'));
}
function getButtonOK() {
    return getwhatEverFrame().element(by.css('#ButtonOK'));
}
function getButtonCancle() {
    return getwhatEverFrame().element(by.css('#ButtonCancle'));
}

I don’t see where POM Design just allows flat structures.

Agreed. There are a few “Katalon insiders” that would like you (us) to think that Katalon supports a POM. It sort-of does, but it certainly does NOT promote or even foster the use of a POM. And the Object Repository (combined with the recording tool) actively prevents it (as you’ve come to discover).

Stop using the recorder.

Build your own TestObjects and ignore the OR.

Build your own keywords and store them in your own POM model in the Keywords structure.

Build and store your Test Cases into a logical Page-based heirarchy.

2 Likes

This disappoints me. My company is willing to pay for licenses for software, but this is a major point which would keep me away.
As POM should remove redundancy from the test code, even within the POM redundancy should be very low. But i don’t see it given in this Object Repository. The OR just provides a flat file structure with no inheritance for common element like frames or panels. Their paths needs to copied over and over again.
It doesn’t allow to fully implement the DRY principle, it’s still WET. ‘Code’/Pathes for the same function/elements needs to be change at multiple places instead of a single one.

Can you explain this a bit more in detail? How shall create a POM in the Keywords structure? How will it be used (just by code and without the manual view?)?

The recorder and the manual editor were attracting my tester coworkers which are not that familiar with real coding.
But without the OR and the recorder we are back at much coding. So why should i use Katalon? I really want(ed).

Got any body else and advice how handel the POM / OR in Katalon Studio?

Katalon is essentially free - certainly at the point of use. Many parts of it are now open source. You can modify, extend and improve Katalon using the Katalon platform (plugins and addons, essentially) so I’d prefer not to get into the TCO of Katalon - it’s not my interest, it’s not my “field” of expertise, and it’s not the focus of this community and what we discuss here. Plus, it’s a testament to the decisions made by the company that Katalon is the best testing platform available (by a long way) allowing a programmer to modify its subsystems to suit their needs.

With that in mind, now consider the forum category in which we’re discussing this topic - Feature / Imporovement Suggestions. Katalon Team are listening. Nobody is claiming Katalon is perfect - far from it. Katalon Team (expressed to me many times privately by @YoungNgo) want to improve Katalon and that is why they are listening. Being the best is one thing. Staying the best is hard work and is not achieved by standing still. Katalon clearly know this.

If your issues are that some caliber of your workforce are not able to use a particular tool in a particular way, that is a matter for you and your organization. Nobody is born knowing any of this stuff. If you need to train people, then train them (instead of bemoaning a particular tool).

That said, if you are a trained person, able to detect the lack of DRYness afforded by the OR, then do the obvious… stop using the OR. Better still, stop trying to satisfy two very different audiences at the same time. Good luck trying to find a tool that can do that.

I hope you don’t think this is some kind of personal attack – it’s not. I’m giving you straight answers to honest questions (or points of discussion) that you brought up. They’re colored by my experience and slanted toward my purpose (if that purpose suits yours, great and if not, well, that’s maybe not so great).

I don’t use Manual View, only Script View.

  1. Manual View is like Lego. You can construct things using prefabricated Lego bricks.
  2. Script View lets you manufacture bricks and construct things using them.

Those are your choices. If you need elements of #2 you’re likely to stay there, where the power is. If some of your coworkers need training to help them understand how to use #2, train them.

Building a POM using the scripting tools in Katalon is a relatively pain free process. At the present time, this is best accomplished using Katalon’s Custom Keyword subsystem. What you’re actually doing is defining new Groovy packages and classes which you can use to reflect the functionality of the pages in your AUT.

A very simplistic POM might look like this:

public class BizLogic {
  // stuff about the business rules managed by the AUT
}

public class BasePage extends BizLogic {
  // Methods and properties common to all regular pages
}

public class HomePage extends BasePage {
  // Methods and properties reflecting the home page
}

Obviously examples can get lengthier the more you try to capture all the possibilities that may appear in the real-world so I’ll stop there and let you think about it. And besides, you’re not even sure you want to stay with us yet :confused:

Here are the links you need to understand Keyword creation:

https://docs.katalon.com/katalon-studio/docs/introduction-to-custom-keywords.html

https://docs.katalon.com/katalon-studio/docs/sample-custom-keywords.html

Hope that inspired you to bite the bullet and get coding.

1 Like

I’ve found that while Katalon doesn’t currently promote or encourage the POM structure, it certainly facilitates it quite well. We’ve had massive success with our POM using Katalon.

I agree with Russ, the Recorder should not be a driving force of your POM creation, and this is true for other test automation tools. Writing a scripting interface (a POM) by hand may seem like a daunting task, and it is, but so is web development and application programming. There’s no “Recorder” for those either. A strong scripting interface requires as much diligence as any software project.

On the note of the Object Repository, as Russ has said, you don’t need to use it. In fact, while I was a fan of it originally, I too have moved away from it and just have my page objects own the locators.

1 Like

@Katalon-Studio-Team: Having (multiple) parent objects in the OR would improve the DRYness of the test code. How are you about that?
I don’t see why it’s against POM.

In the popular/current vernacular, “meh”.

  1. Test Objects create a wrapper around artifacts that contain CSS and/or xpaths used to locate HTML elements on the page.

  2. CSS and xpath can be used in JavaScript to locate elements (web pages themselves only use CSS and JavaScript).

To answer your question, let me ask you a rhetorical question: why would I want to use #1 which would create a bunch of TOs I don’t need when I know how to use #2 (JS and CSS) to directly target an element on the page? So in answer to “How are you about that?”, why would I fly from London to New York via Cape Town?

I don’t know what “it” is.

Could you describe this more in detail? It’s hard to grasp what you mean.

My experience with other tools is a different one. I have seen fully working ORs in QF-Test (Java) and Ranorex (Web, WPF). Even code / coded tests are relying on them. They are the base for anything else.

Maybe i should explain this a bit more: This other ORs working a bit different then the one for Katalon Studio.
KS - flat OR:
Any object in the KS-OR is fully independent form the others. It has all informations it needs to identify the element in the UI (e.g. an xpath). This means a certain WETness, because for example a changed panel name, included in multiple elements xpath, needs to be changed in all this elements via search&replace. Am i wrong here?
Others - hierarchical OR:
This different ORs allow hierarchies of objects/elements. There are objects just to arrange a certain order (mostly a mirror of the actual application).
Every object has only the substring of the xpath (just for example) it needs to find the element relative to its parent object. If a test interacts with a certain element, e.g. a button, this element concatenates all substrings from his ancestors like frames or panels to the full path. If a panel name changes, there is only one place to update it. This is fully DRY.
I not sure if for Katalon Studio here all selection methods (xpath, attributes, css) need to be available.

Where are unneeded ‘bunch of TOs’ are coming from? Do you mean ordering elements like panels or frames?
For identifying an object, in my experience, in most cases is need information’s from its ancestors (some, not all). It’s quite seldom that an element has totally unique identifiers (or they are very unreliable, because dynamical generated).
How do you avoid WETness at css and xpath of the elements?

I’m driving from one navigation point one of the route to another. Go left there, drive straight for x, go right there, “Welcome to your destination”.

Kind Regards
Sebastian

True statement.

True statement.

The things you already identified. The OR and the Recorder.

Firstly, I don’t use TOs and I don’t use the OR (for the reasons I mentioned). So I don’t have a bunch of TOs to manage and a bunch of CSS paths to maintain. And I don’t get “stale element” references because I target HTML elements directly using CSS (in JS).

You understand that I consider TOs to be “Cape Town”, a stopping off point I don’t need.

To briefly give some context:

We have a set of applications that are shared among multiple different clients. Any given application has a base implementation that is shared among all clients, as well as a client-specific implementation that overrides/extends functionality to suit a particular client’s needs. As a result, we needed to build a scripting interface that matches this structure as closely as possible.

In Katalon, we did this by utilizing “Custom Keywords”. At its core, custom keyword functionality is really just a set of user-defined classes organized into packages, just like any other Java/Groovy software project. As such, we built our POM using custom keywords. So for instance, we have a base “LoginPage” object that encapsulates all of the login page widgetry that is the same between every instance of the application, but also several client-specific “LoginPage” objects that extend this base class to handle slight variations from the base implementation.

Yes, I agree with you, Katalon’s OR is indeed flat (however, there’s a way around this, see below). In other words, there’s no way to find one element relative to another element through normal usage of the API. I will show you a way that it could be done with the API, but then you may as well skip using the OR completely and just manage locators from within your page objects:

  • Hopefully we can agree that the Object Repository fundamentally acts as a container for locators. I’m unfamiliar with how the other tools you’ve mentioned handle OR functionality, but I imagine this is true for them as well.

  • With this in mind, lets pretend we want to find a link that exists within a panel. Normal usage of the Katalon OR would mandate that you create a TestObject that contains an xpath that includes BOTH the panel element AND the link element:

  • You would then locate the element in your page object or script as follows:

    WebElement link = WebUiCommonHelper.findWebElement(findTestObject('path/to/test/object'), 30);

  • However, if for whatever reason the id for the panel element changed, and you had a bunch of other elements that were located relative to this panel, then you would need to change ALL TestObjects that included the panel in their xpath. I agree with you: that’s a pain, and I believe this is the source of your disappointment.

  • There’s definitely a way to do what you’d like though. Pretend instead that we have two separate TestObjects, one for the panel, and one for the link:


  • In your page object or script, you can locate this by either combining the xpaths and locating once, or you could locate the panel first, then locate the link relative to the already-located panel:

    // Combine xpaths, then locate once:
    String panelXPath = findTestObject('path/to/panel/object').findPropertyValue("xpath");
    String linkXPath = findTestObject('path/to/link/object').findPropertyValue("xpath");
    WebElement link = DriverFactory.getWebDriver().findElement(By.xpath(panelXPath + linkXPath));
    
    // Locate panel, then locate link relative to panel:
    WebElement panel = WebUiCommonHelper.findWebElement(findTestObject('path/to/panel/object'), 30);
    WebElement link = panel.findElement(By.xpath("." + findTestObject('path/to/link/object').findPropertyValue("xpath")));
    
  • After all that though, you may as well simply have your page objects take ownership of the xpaths, and skip using the OR altogether, cutting out the middle-man. This is @Russ_Thomas’s argument. Then you could just have getter methods for your xpaths within the page object, and call those when you need to locate something:

    public class SomePage {
    
        public void clickLink() {
            WebElement link = DriverFactory.getWebDriver().findElement(By.xpath(getPanelXPath() + getLinkXPath()));
            link.click();
        }
    
        public String getPanelXPath() {
            return "//div[@id='myPanel']";
        }
    
        public String getLinkXPath() {
            return "//a[@id='myLink']";
        }
    
    }
    
  • For better or worse, this essentially means that you, the engineer, are responsible for the parent/child relationship of your locators in Katalon.

2 Likes

All of which is true - not only that, Brandon has nailed completely what I’ve been (failing?) trying to say.

In addition to that, I know how the identifiers are constructed – i.e. they are derived computationally using the same computational algorithms as the AUT itself uses. This makes them computationally verifiable. When they fail, in essence, I haven’t found a bug in my test, I’ve discovered a bug and/or regression in the AUT. And that, is my job. :sunglasses:

So, where Brandon is suggesting something like:

public String getPanelXPath() {
  return "//div[@id='myPanel']";
}

I might have something like

grid.someSetMethod(gridRef("0", "txtNAME"), value)

Where gridRef returns a CSS selector for a text control in an arbitrary column on a specific row (“0”) in the grid in whose context it is called. IOW, I rarely see “wet” (as you call them) CSS selectors. They’re computed. Correctly (usually :smiley: ).

I’m grateful @Brandon_Hein. Your comment nails down what @Russ_Thomas and i where ‘fighting’.
Thanks to you both for your endurance.

Ok, i thought you meant by using the OR. It wasn’t clear to me, that you did with coding like Thomas.

Totally. And that’s the point where i would like to see the OR improved / working differently (via plugin ?).
I wish the OR, as locator storage, would be fully equivalent to any code. This should increase the acceptance by new customers.
I would be pissed, if i had spent month of effort in the actual OR to realize later, that i have to fully convert it to code to drop that level of WETness.

I fully understand and agree on that.

@Russ_Thomas: Maybe we passed each other here and i was a bit unclear.
In the actual state of the OR i fully understand your perspective.

  1. I’d like to see the OR improved to be a full equivalent to code.
  2. (maybe the better 1.) I see UI and code just as different perspectives by personal choice how to work. With the premise, that the UI is fully developed (which the OR is actually not). I once had such software.

Sadly once again i’m troubling to fully understand your comment. I guess i’m missing some context your are having? I give it a try.

Sounds you are a lucky guy. I’m not in such a situation.
Do you mean dedicated test locators for the AUT? And they are computed by the build process of the AUT?
I’m having either by developers manual set test locators.
Or the ‘normal’ locators, all the css information elements are having. Which i don’t see how to predict and can switch on daily base. Especially if generated numbers. And here i’m not sure if its an good idea to reverse engineer this part of the build process.
What am i missing?
(This is the part i wanted to discuss in the other discussion. To me it’s not about how to improve the OR but how to work without it)

Kind Regards
Sebastian

Nothing. You are describing a much more dynamic (even volatile) situation. But even then, locators (xpath or css) can be constructed to safely access those elements. If xpath is your preference, see @Brandon_Hein, JS/CSS see either of us.

In essence, yes. They are predictable (at least, the vast majority are). If I use the same predictable techniques, I’m safe. I gave you an example in code.

Hi Liam_B,

Any chance that this wil be implemented in Katalon?

It would be great if we would have the option to select a general object as a parent (Not a parent iframe or Shadow Root parent) when creating an object.

1 Like