130 likes | 288 Views
Learn through Experience -- We differentiate our training and development program by delivering Role-Based training instead of Product-based training. Ultimately, our goal is to deliver the best IT Training to our clients. Attendees also learn: 1. Resume Preparation Guidelines and Tips 2. Mock Interviews and Interview Preparation Tips For more visit http://www.quontrasolutions.co.uk/selenium-training-classes/
E N D
Automation with SeleniumPresented By Quontra SolutionsIT Courses Online TrainingCall Us: 20-3734-1498Email: info@quontrasolutions.co.uk
SeleniumYou can’t be good at everything • How Selenium Remote Control works • You launch a server on your test machine. • Your tests connect to that server via IP. • The server launches a browser, with selenium CORE embedded as javascript into the page. • Selenium CORE simulates user actions with javascript.
The javascript sandbox The Good The Bad • Doesn’t steal your mouse/keyboard. • Works with any browser that uses javascript • Works for any OS that supports java. • Very fast page interactions. • Large API • Supports a variety of programming languages. • Can be run on remote machines • Can’t see anything outside the page object. • Not all browsers support all functionality. • Some pages aren’t automatable. • Can’t see inside third party apps • XSS Limitations
WebDriver Introduction • A different way of automating the browser. • Create a browser-specific driver to control the browser directly. • Have to do this for each browser! • Object oriented API • Doesn’t need a real browser • No javascript limitations • No need for a server. • Isn’t as delicate as selenium.
Selenium 2 • Went into Beta Dec 24th. • WebDriver + Selenium • The two projects have merged (literally) into Selenium 2.0 • Large browser support and no javascript limitations. • No server • The old API’s are still available. • New API’s are becoming available.
Automating with Selenium 2 • You have 2 options: • IWebDriver • This is just the WebDriver api • Doesn’t support a lot of browsers. • Will need to change all your tests. • WebDriverBackedSelenium • Uses the old Selenium 1 API • But uses WebDriver to run things if possible • Can use selenium 1 if the browser isn’t supported.
The WebDriver API • Object Oriented • Doesn’t break nearly as often • Handles pageloads automatically • Fewer problems automating • Somewhat more complicated API • selenium.type(“password”,”thisIsMyPassword”); • driver.findElement(By.id("password")).sendKeys(“thisIsMyPassword"); • By.Id, By.Xpath, By.Name, By.ClassName, By.PartialLinkText • All the supported browsers work really well • Can extend the API to add custom functionality. • Works well with a Page Object design model.
Page Object Design Pattern • Adds a layer of abstraction into your code. • Helps to organize your code once it grows large. • All automation is automatically reusable and shareable. • A way to separate tests from re-usable functions. • A way to store information about how the system works. • A way to specify what page functions start on, and what page they end on. • A way to programmatically break your tests when functionality changes. • Makes code maintenance easier. • There is even a PageFactory class available to automatically create them.
How does it work? • Each page is defined as it’s own class. • Actions (including navigation) are represented as functions for a class. • Each function returns a new Page object, signifying what page the actions stops on. • Your tests “know” what page you are on, and will only give you access to functions available to that class. • Tests only talk to the page objects. • Page objects only talk to the driver. • Elements on the page are stored as variables for the page object. • Automatic page validations can be stored in the constructor for each page object. • Tests become a string of well defined functions, not meaningless gibberish. • Tests can be grouped by namespace. • Class Inheritance can be used to define functionality to a set of pages. • We can make functional logic transparent to the tests by returning different inherited classes.
Bad Tests globalVars.logDescription = "log in"; globalVars.selenium.Open(globalVars.mobiUrl); functions.type("userId", globalVars.studName + "1"); functions.type("password", globalVars.studPass + "1"); functions.clickAndWait("signInBtn"); selenium.click("//a[@id='discussions']/span"); selenium.click("//a[@id='thingsToKnow']/span"); globalVars.logDescription = "Checking elements on happenings:by date page"; selenium.waitForElementNotVisible("//div[@id='THSContainer']//span[@class='ajaxLoadingHeader']"); selenium.waitForElementVisible("//div[@id='THSContainer']/ul[1]/li[1]"); selenium.click("//div[@id='THSContainer']//span[@class='replytext']"); selenium.click("backButton"); selenium.waitForElementVisible("//div[@id='TTHContainer']/ul[1]/li[1]"); selenium.click("//div[@id='TTHContainer']//span[@class='replytext']"); selenium.click("backButton"); globalVars.selenium.Select("byDateFilter", "label=Things Happening Soon"); selenium.waitForElementVisible("//div[@id='THSContainer']/ul[1]/li[1]"); selenium.click("//div[@id='THSContainer']//span[@class='replytext']"); selenium.click("backButton"); globalVars.selenium.Select("byDateFilter", "label=Things That Happened");
Better Tests [Test] public void testByDateTab() { funtions.loginMobi(); selenium.click("//a[@id='discussions']/span"); selenium.click("//a[@id='thingsToKnow']/span"); functions.verifyThingsToKnow(); functions.verifyThingsHappeningSoon(); selenium.Select("byDateFilter", "label=Things That Happened"); functions.verifyThingsThatHappened(); }
Good Tests [Test] public void testByDateTab() { selenium.Open(Moby_Common.MobyLoginUrl); LoginPageloginPage = new LoginPage(selenium); HappeningsPagehappeningsPage = loginPage.loginAs(Common.stud1Name, Common.stud1Password); happeningsPage.waitToLoad(); Assert.That(!happeningsPage.isByTypePageLoaded()); Assert.That(happeningsPage.isByDatePageLoaded()); Assert.That(!happeningsPage.isByCoursePageLoaded()); happeningsPage.filterResults("byDateFilter","Things That Happened"); Assert.That(happeningsPage.isVisible("TTHContainer")); happeningsPage.filterResults("byDateFilter", "Things Happening Soon"); Assert.That(happeningsPage.isVisible("THSContainer")); happeningsPage.filterResults("byDateFilter", "All Types"); Assert.That(happeningsPage.isVisible("TTHContainer")); Assert.That(happeningsPage.isVisible("THSContainer")); }
The Page Object: public class HappeningsPage : WebPageBaseClass { private string _loadingImage = "//span[@class='ajaxLoadingHeader']"; private string _moreLink = "more"; public HappeningsPage(ISelenium selenium) { this.selenium = selenium; this.title = "Happenings"; this.url = "index.html"; assertPageLoadedCorrectly(); } public HappeningsPagewaitToLoad() { waitForElementNotVisible(_loadingImage ); return new HappeningsPage(selenium); } public ContentItemPagegoToItem(string type, string name) { click("//div[@id='" + type + "']//span[text()=\"" + name + "\"]"); return new ContentItemPage(selenium); } public HappeningsPageclickMoreLink() { click(_moreLink); return new HappeningsPage(selenium); } public HappeningsPagefilterResults(string id, string name) { selectDropdown(id, name); return new HappeningsPage(selenium); } }