Jatin
Jatin

Reputation: 670

Setting up Page objects in Protractor

I am new to protractor and making my hand dirty with all the various tips and tricks to make my code more modular and efficient enough. I create a page object for my specification file. Page object:

var mapFeedBackpage=function(){

    REPORT_ROAD=element.all(by.css("div[ng-click=\"setLocation('report_road')\"]"));
    ROAD_NEW=element.all(by.css("div[ ng-click=\"mapFeedBack.editObject= mapFeedBack.createMapObjectModel();setLocation(mapFeedBack.noMap?'road_new':'choose_location_road_new/road_new')\"]"));
    ZOOM_IN=element(by.css('div[ng-click="zoomIn()"]'));
    ROAD_NAME=element(by.model("mapFeedBack.editObject.roadName"));
    SUBMIT_ROAD=element(by.css('button[ng-click="onSubmit({reportType: reportType})"]'));
    HIGHWAY_OPTION=element(by.model("mapFeedBack.editObject[attrs.select].selected")).$("[value='string:app.road.roadType.highway']");


    };

    module.exports=mapFeedBackpage;

Now the problem is that when i write this.REPORT_ROAD in the page load file my test fails saying it cant find the REPORT_ROAD variable but when I remove this for the variable it works. Now, I am wondering why is that so? Can anyone please explain me this? I used the Page Load guide : http://www.protractortest.org/#/style-guide#page-objects

My Spec file code is as follows :

var mapFeedBackpage=require('./mapFeedBack-page.js')
describe("Map feedback Automation",function()
{

var mapFeedBack= new mapFeedBackpage();

    it("Check if the Url works ",function() //spec1
    {
        browser.get(browser.params.url);
        expect(browser.getCurrentUrl()).toContain("report");
        browser.sleep(browser.params.sleeptime);
    }); 


    it("test browser should reach report road option",function() //spec2s
    {
        REPORT_ROAD.click();
        expect(browser.getCurrentUrl()).toContain("report_road");
        browser.sleep(browser.params.sleeptime);
        browser.sleep(browser.params.sleeptime);
    });


    it("test browser should reach report road missing",function() //spec3
    {
        ROAD_NEW.click();
        expect(browser.getCurrentUrl()).toContain("choose_location_road_new/road_new");
        browser.sleep(browser.params.sleeptime);
        browser.sleep(browser.params.sleeptime);
    });


    it("test browser should zoom on map ",function() //spec4
    {


    var EC = protractor.ExpectedConditions;

    for(var i=0;i<3;i++)
    {
        var elm = ZOOM_IN;
        browser.wait(EC.elementToBeClickable(elm), 10000);
        elm.click();
        browser.sleep(browser.params.sleeptime);
    }



    }); 

    it("Should click on ok option",function() //spec5
    {
            var EC = protractor.ExpectedConditions;
        var elm = element(by.buttonText('OK'));
        browser.wait(EC.elementToBeClickable(elm), 10000);
        elm.click();

        expect(browser.getCurrentUrl()).toContain("road_new");

    }); 



it("test browser should reach report road option",function() //spec6
    {

        browser.sleep(browser.params.sleeptime);
        expect(browser.getCurrentUrl()).toContain("road_new");

    }); 



    it("should  enter a road name",function()   //spec8
    {       

     browser.sleep(browser.params.sleeptime);

     var testroadname = browser.params.testroadname;


     ROAD_NAME.sendKeys(testroadname);
    browser.sleep(browser.params.sleeptime);



    });


        it("should check the type of road is highway",function()  //spec9
    {

    HIGHWAY_OPTION.click();
});


        it("should  submmit the map feedback",function()  //spec10
    {       

    SUBMIT_ROAD.click();
    browser.sleep(browser.params.sleeptime);
    });





});

Upvotes: 0

Views: 155

Answers (1)

Ram Pasala
Ram Pasala

Reputation: 5231

In your page objects, you should declare the elements with "this", consider it as a pronoun in english language -"he", "she", "it" you use for referring a person or an object, similarly you can access the elements anywhere in your code/test cases by this.

http://www.protractortest.org/#/style-guide#page-objects - this style guide clearly states that use "this" with your elements in the page objects.So your code should like this:

var mapFeedBackpage=function(){

this.REPORT_ROAD=element.all(by.css("div[ng-click=\"setLocation('report_road')\"]"));
this.ROAD_NEW=element.all(by.css("div[ ng-click=\"mapFeedBack.editObject= mapFeedBack.createMapObjectModel();setLocation(mapFeedBack.noMap?'road_new':'choose_location_road_new/road_new')\"]"));
this.ZOOM_IN=element(by.css('div[ng-click="zoomIn()"]'));
this.ROAD_NAME=element(by.model("mapFeedBack.editObject.roadName"));
this.SUBMIT_ROAD=element(by.css('button[ng-click="onSubmit({reportType: reportType})"]'));
this.HIGHWAY_OPTION=element(by.model("mapFeedBack.editObject[attrs.select].selected")).$("[value='string:app.road.roadType.highway']");


};

module.exports=mapFeedBackpage;

Your spec should look this:

var mapFeedBackpage=require('./mapFeedBack-page.js')
describe("Map feedback Automation",function()
 {

 var mapFeedBack= new mapFeedBackpage();

it("Check if the Url works ",function() //spec1
{
    browser.get(browser.params.url);
    expect(browser.getCurrentUrl()).toContain("report");
    browser.sleep(browser.params.sleeptime);
}); 


it("test browser should reach report road option",function() //spec2s
{
    mapFeedBack.REPORT_ROAD.click(); //This is a cleaner way to access page objects
    expect(browser.getCurrentUrl()).toContain("report_road");
    browser.sleep(browser.params.sleeptime);
    browser.sleep(browser.params.sleeptime);
});

 it("test browser should reach report road missing",function() //spec3
{
    mapFeedBack.ROAD_NEW.click();
    expect(browser.getCurrentUrl()).toContain("choose_location_road_new/road_new");
    browser.sleep(browser.params.sleeptime);
    browser.sleep(browser.params.sleeptime);
});

The above mentioned way helps referencing the elements efficiently and even if the template of the application changes, you only need to change page objects rather than your test cases. Hope it clarifies your question !

Upvotes: 1

Related Questions