18 January 2026:
Sahi Pro is an enterprise grade test automation platform which can automate web, mobile, API, windows and java based applications and SAP.
This forum is now archived and is in read-only mode. Please continue discussions on our improved new Sahi Pro Community forum.
Sahi Pro is an enterprise grade test automation platform which can automate web, mobile, API, windows and java based applications and SAP.
Anyone using page objects in Sahi
I'm interested in introducing a page object pattern to my sahi scripts and wanted to see if anyone here in the forum is doing this too... The pages themselves seem pretty straight forward but I'm interested in HOW you incorporate them into your tests. How you call them from your scripts and how you manage them in general. Any examples you could give would also be great.
Thanks a bunch,
Brian
Thanks a bunch,
Brian
Comments
In addition, I'm making some assumptions in OO javascript and I'd like to know if I'm using them correctly. For example, verifyPage is (in my mind) a private function and thus, I don't use "this" so when declaring it... is that correct use for such a thing?
Thanks a bunch!
Brian
this looks quite good, but I don't think it does scale well. I am currently automating a ticket shop where you can choose from thousands of events. To test specific page details, I may have to write an own page object for each event. Well.. as I think about it.. it may be no great difference. I have no idea, I might just try it to get an impression. An events page object won't let me test details.. I might have to write some general event page object and other, more specific objects for that kind of page.
One question arises: What do you do with reoccurring objects? Like having an _submit("next") on many pages? Do you refactor this occurrences into some object? Do you stores them as global variables?
Your second code example is more beautiful, I just like that pattern more.
Regards
Wormi
Thanks for the reply. I have the same questions you have and am hoping to start a discussion to learn the answers myself. My second example was a refractor of my first, using an object literal... I too think it flows much better and doesn't require instantiating with "New". It did require a that=this workaround for scope... hope i'm not breaking any rules with it
I started playing with page objects because I have loose code in my script (for navigation and such) that could cause my scripts to break shout they change... plus, I like the readability that I could get by using these objects.
As for reocurring objects (_submit("next") or even navigation), I'd think you'd make that their own objects and include them... I'll have to play with it too.
I've read a lot about page objects online but haven't really had the breakthrough moment where I have my head fully around it. I was hoping to find others that were using them push me in the right direction (or tell me I'm crazy).
Brian
I remember, I once tried something similar, not really object per page, more like object per context... but I didn't explored it further because I couldn't find an IDE which aided me with content assist on the different return types.. may the code explain this better:
With a good IDE (I recently discovered webstorm... quite neat) and some documentation I could easily write tests as oneliners. If the documentation on your functions is really good, you can have everyone writing test, you just need to write
$Goo -> Content assist
"Use this for the Google Homepage"
$GoogleHome. -> Content assist
"Use this to navigate to... Use this to search after, @param text, @return $GoogleResults"
GoogleHome.visit().searchFor("javascript page object pattern"). -> Content assist on the $GoogleResults functions
This seems pretty nice and readable (my opinion, correct me if you think different), but I just save some linebreaks and some variables.. worth it? I don't know.
Storing elements/constants in objects is ok, but I can't figure out the sorting.. context: or type?
When you translated you sites logic and flow into page objects, it might be pretty fast to write tests and easy to refactor, but I just can't imagine me writing >1000 page objects. Maybe, as I said earlier, we could use prototypes. Let a specific page inherit the navigation, logos etc....
The point of page objects, in my mind, is to encapsulate the page services--so changes only need to occur in one place (instead of hundreds) and perhaps more importantly, code readability. For instance, I could had the following line to ANYbody and they'd know what it was doing:
GoogleHomePage.searchFor("I like eggs");
This seems to be the promise of page objects. These offerings would also lead me to think separating the elements/actions to go against the entire idea. I'd like a page to offer the "services" of a textbox, link, button, etc.... And although it would take some upfront time, I think it would likely pay off. Towards this goal also, I would add elements to a page object, only as needed... in that way, the upfront costs would be mitigated.
As for common objects like nav, I would add these to their own object and/or incorporate them into a basePage class that could be inherited into other page objects... I've not tested it yet but that seems logical...
Thoughts? Maybe it's only Wormy and I thinking about this?
Brian
I think you are right, upon finishing the page objects, there is no great difference to what I use right now. But I'd like to hear some other opinions too.
this.$x is parsed correctly in Sahi Pro. So this is valid code:
Regards,
Narayan
I just tried (again) using this.$url in the code and it fails with:
This is why I did the $that=this workaround. I've only tried this on my Mac however... perhaps it's a bug on Mac? I'll try it on my PC when I get to work.
Wormy, I dig the chaining... and that's the idea.
Thanks,
Brian
Brian
The bad thing is, I have to use that $this=this or it won't work.. maybe because of Sahi OS...
and method chaining over various objects isn't working too (it used to work a few month ago), but this is no bad thing. I would have made my tests a one liner, now its pretty obvious when a page changes. My setup:
Basic Page
Abstract User and Navigation Object like:
Constant Element File
The benefit:
I tests are easy to read and extremly fast to write (took 3 hours to write and refactor the objects, now I write tests within 20 min). Nearly instant refactor as you put every pages features into seperate functions. Higher Objects: shorten the tests, easy to read $navigation.goThere().doThat().goSomewhereCompletlyElse().
onPage function: yeah.. execution takes longer, but I can make sure that the page I need is present and can have some standard error handling/logging when something isn't working as expected.
Well.. thats pretty it. When the scripts fail somehow, other than "onPage" functions will get a similar error handling.
Next Step: prototyping the page object..
Does this make sense?
Seems you have used OO pretty well..
I tried it too but, got a problem on 'this' object so in my implementation, i only just use object variables.
Right now, i have a function for verifying a page and for buttons that i can click within pages.
Keep posting your updates.
try to use var $this=this, works for me. What you did there looks quite promising, wrap an object around and you are done with the page object
btw, this is no real object orientation so far. Yes, we use objects, but there is no scope whatsoever, no inheritance, polymorphism etc.
But we could add that easily. I talked about page navigation and company logos which are present on all pages. We could easily define a navigation prototype which pages can inherit... here is an example which totally could be more abstracted, I think:
my next step would be to write a $Page prototype
I dig the elegance of the object literal solution to this but it's lack of inheritance is problematic. I can't seem to find a way to inherit a common object, such as a header or navbar. Obviously, you could just make a navbar it's own object literal and go with it... but it'd be nice to be able to encapsulate it into the relevant page objects.
I've tried a bunch of different things to work around this, including making the common objects constructors... but I can't seem to get my head around it.
Anyone else have a solution?
Eg. given the following code...
Of course filterBy.images() does work, but I want to find a way to inherit filterBy into GoogleResults (and other pages that include this common object). I tried making it a constructor, returning the functions, etc....
Anyone have a clever solution?
Thanks,
Brian
something like this... hope you can improve it
I hope you get my idea
At least for the second handicap there is a solution. Taken from http://blog.anselmbradford.com/2009/04/05/object-oriented-javascript-tip-overriding-tostring-for-readable-object-imprints/ I can create a page prototype:
For specific pages:
HomePage.checkheading() will now fail with "Page: Home Page has no function checkheading" istead of "Object [object] has no ...". This is pretty handy when you have many pages and some generic function names.
Anyway, here's my working example. I left the $this=this (I preferred Wormy's way of doing this to my own (thanks Wormy!)) so this should also work on the current OS version.
I cleaned some things up and removed unnecessary"$" and $this=this statements, so this code will currently only run on Sahi Pro. I added comments to try and explain things a bit and I also updated how I'm calling the common SearchFilter to be a bit more elegant.
Hope this helps!
GlobalWorming, I'm looking forward to see how you'll use inheritance in your example...
Thanks again.
I am trying the same thing as you guys discussed above, am also stuck in creating the page prototype. Am getting the page name as a string and want to have a function to dynamically include the page library and return the reference to the page objects and functions. Kindly let me know if you are able to create a prototype for a page. ? and creat the page references dynamically ?
//trying to do this.
var $home = new Page("Home")
$home.navigate();
$home.checkPage();
//Page function
function Page($p_sPage){
_dynamicInclude("../Pages/"+$p_sPage);
var $global = this;
return new $global[$p_sPage]; // trying to convert string into an object, tried different ways including object.create() no luck
}
Any help on this will be appreciated.
thanks
var $global = this; // this line of code should be in global name space
//Home.js - create a library with respect to the page
function Home(){
//objects and methods w.r.t Home Page
}
//Page function
function Page($Page){
_dynamicInclude("../"+$Page+".js");
var $a_oPage = $global[$Page];
return $a_oPage;
}
//Script
var $home = new Page("Home"); //create a reference to the Home object
$home .checkPage(); // access the methods
$home .Navigate();
Thanks,
Balaji
can i know please, what is the advantage of using "page objects" coding technique instead of existing sahi script technique