این قسمت به دلیل طولانی بودن و اینکه ممکن است از حوصله خواننده برای مطالعه یکباره خارج باشد، به دو بخش تقسیم شده است
سعی داریم با استفاده از کلاس “myclass” جاوا که در آموزش قبلی ایجاد کردیم، یک اسکریپت WebDriver ایجاد کنیم که:
- صفحه Homepage تور Mercury را واکشی کند.
- عنوان آن را تایید کنید
- نتایج حاصل از مقایسه را چاپ نماید
- قبل از پایان تمام برنامه، آن را ببندد
WebDriver Code
در پایین یک کد واقعی WebDriver برای Logic ارائه شده توسط سناریوی بالا درج شده است.
نکته: با شروع به کار با فایرفاکس ۳۵، شما باید برای بهرهبرداری از Web Driver، از Gecko Driver که توسط موزیلا ایجاد شده است استفاده نمایید. Selenium 3.0 با Gecko و Firefox مشکل سازگاری(Compatibility) دارد، و تنظیم آن به شکل درست میتواند یک کار دشوار باشد. اگر کد کار نمیکند، به نسخه فایرفاکس ۴۷ یا پایینتر Downgrade کنید. همچنین شما میتوانید اسکریپتهای خود را در Chrome اجرا کنید. سلنیوم با Box برای Chrome کار میکند. شما فقط باید ۳ خط از کد را تغییر دهید تا اسکریپت شما با Chrome یا Firefox کار کند.
package newproject; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; //comment the above line and uncomment below line to use Chrome //import org.openqa.selenium.chrome.ChromeDriver; public class PG1 { public static void main(String[] args) { // declaration and instantiation of objects/variables System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); //comment the above 2 lines and uncomment below 2 lines to use Chrome //System.setProperty("webdriver.chrome.driver","G:\\chromedriver.exe"); //WebDriver driver = new ChromeDriver(); String baseUrl = "http://demo.guru99.com/test/newtours/"; String expectedTitle = "Welcome: Mercury Tours"; String actualTitle = ""; // launch Fire fox and direct it to the Base URL driver.get(baseUrl); // get the actual value of the title actualTitle = driver.getTitle(); /* * compare the actual title of the page with the expected one and print * the result as "Passed" or "Failed" */ if (actualTitle.contentEquals(expectedTitle)){ System.out.println("Test Passed!"); } else { System.out.println("Test Failed"); } //close Fire fox driver.close(); } }
توضیح کد
Import کردن Packageها
برای شروع، شما باید دو Package زیر را Import نمایید:
- *.org.openqa.selenium: حاوی کلاس WebDriver مورد نیاز برای نمونهسازی یک مرورگر جدید است که با یک Driver خاص بارگذاری شده است.
- org.openqa.selenium.firefox.FirefoxDriver: شامل کلاس FirefoxDriver مورد نیاز برای نمونهسازی یک Firefox-Specific Driver بر روی مرورگر نمونهسازی شده توسط کلاس WebDriver است.
اگر تست شما به Actionهای پیچیدهتر مانند دسترسی به کلاسهای دیگر، اسکرینشات گرفتن از مرورگر یا دستکاری فایلهای خارجی نیاز دارد، قطعا شما نیاز به Import کردن Packageهای بیشتری خواهید داشت.
نمونهسازی Objectها و متغیر(Variable)
به طور معمول، این قسمت چگونگی نمونهسازی یک Driver Object را تشریح میکند.
یک کلاس FirefoxDriver بدون پارامتر به این معنی است که FireFox Profile پیشفرض توسط برنامه جاوا ما لانچ میشود. FireFox Profile پیشفرض مشابه لانچ کردن فایرفاکس در حالت Safe Mode است(بدون بارگذاری Extensionها).
برای راحتی کار، ما Base URL و عنوان مورد انتظار را به عنوان متغیر ذخیره کردیم.
لانچ یک Browser Session
متد ()get در WebDriver برای لانچ یک Browser Session جدید استفاده شده و آنرا به URLای که شما به عنوان پارامتر آن مشخص کردهاید، هدایت می کند.
عنوان واقعی page را دریافت کنید
کلاس WebDriver متدی به نام ()getTitle دارد که همیشه برای بدست آوردن عنوان صفحهای که در حال حاضر بارگذاری شده است، استفاده میشود.
مقادیر مورد انتظار(Expected) و واقعی(Actual) را مقایسه کنید
این قسمت از کد برای مقایسه عنوان واقعی(Actual Title) با مورد انتظار(Expected Title)، به سادگی از یک ساختار if-else در Basic Java استفاده میکند.
پایان دادن(Terminating) به یک Browser Session
متد “()close”برای بستن پنجره مرورگر استفاده میشود.
پایان دادن(Terminating) به تمام برنامه
اگر شما از این Command بدون بستن تمام پنجرههای مرورگر استفاده میکنید، تمام برنامه جاوایی به پایان خواهد رسید در حالی که پنجره مرورگر را به صورت باز رها میکند.
اجرا کردن تست
دو راه برای اجرای کد در Eclipse IDE وجود دارد:
- در نوار منوی Eclipse، روی Run>Run کلیک کنید.
- Ctrl+F11 را فشار دهید تا کل کد را اجرا کنید.
اگر همه چیز را به درستی انجام دهید، Eclipse این خروجی را به شما ارائه میدهد: “!Test Passed”
موقعیتیابی عناصر GUI
موقعیتیابی عناصر در WebDriver با استفاده از متد “(()findElement(By.locator” انجام میشود. قسمت “Locator” از کد مانند دیگر Locatorهاییست که در Selenium IDE هم استفاده میشود. اما با توجه به اینکه ما بحث در مورد WebDriver را زودتر آغاز کردیم، موضوع Locatorها در Selenium IDE بعدا مورد بحث واقع خواهد شد. در این زمینه توصیه میکنم، که عناصر GUI را با استفاده از IDE موقعیتیابی کرده و هنگامی که شناسایی عناصر با موفقیت انجام شد، کد را به WebDriver، اکسپورت نمایید.
در اینجا یک نمونه کد از یک عنصر که با استفاده از ID آن موقعیتیابی میشود، ارائه شده است. در اینجا Facebook به عنوان Base URL استفاده شده است.
package newproject; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class PG2 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); String baseUrl = "http://www.facebook.com"; String tagName = ""; driver.get(baseUrl); tagName = driver.findElement(By.id("email")).getTagName(); System.out.println(tagName); driver.close(); System.exit(0); } }
ما از متد ()getTagName برای استخراج Tag Name آن عنصر خاص که ID آن “ایمیل” است استفاده کردیم. هنگام اجرا، این کد باید بتواند Tag Name “ورودی” را به درستی شناسایی کرده و آن را در پنجره کنسول Eclipse چاپ کند.
خلاصه مطالب برای موقعیتیابی عناصر
Variation | شرح | مثال |
---|---|---|
By.className | عناصر را بر اساس مقدار Attribute(ویژگی) "Class" مییابد | findElement(By.className("someClassName")) |
By.cssSelector | عناصر را بر اساس Driverای که ذیل موتور انتخابگر CSS است پیدا میکند | findElement(By.cssSelector("input#email")) |
By.id | عناصر را بوسیله مقدار Atrribut(ویژگی) "id" را موقعیتیابی مینماید | findElement(By.id("someId")) |
By.linkText | Link Elementها را بوسیله متن دقیقی که آن نشان میدهد، مییابد | findElement(By.linkText("REGISTRATION")) |
By.name | عناصر را بوسیله مقدار Atrribut(ویژگی) "name" را موقعیتیابی مینماید | findElement(By.name("someName")) |
By.partialLinkText | عناصر حاوی متن لینک(Link Text) داده شده را موقعیتیابی میکند | findElement(By.partialLinkText("REG")) |
By.tagName | عناصر را بوسیله Tag Name آنها موقعیتیابی میکند | findElement(By.tagName("div")) |
By.xpath | عناصر را از طریق XPath میکند | findElement(By.xpath("//html/body/div/table/tbody/ |
یک نکته در استفاده از (()findElement(By.cssSelector
()By.cssSelector از امکان “contains” پشتیبانی نمیکند. کد Selenium IDE را در پایین در نظر بگیرید:
در Selenium IDE(مذکور در بالا)، کل تست پاس شد. با این حال در اسکریپت WebDriver پایین، همان تست یک خطا ایجاد کرد. چرا که WebDriver از کلیدواژه “contains” در زمان استفاده در متد ()By.cssSelector پشتیبانی نمیکند.
دستورات(Command) مشترک
نمونهسازی عناصر وب
به جای استفاده هر باره از سینتکس طولانی “(()driver.findElement(By.locator” که با استفاده از آن به یک عنصر خاص دسترسی پیدا میکنید، میتوانیم یک شیء WebElement را برای آن نمونهسازی کنیم. کلاس WebElement در بسته”*.org.openqa.selenium” قرار دارد.
کلیک بر روی یک عنصر
احتمالا کلیک کردن شایعترین روش تعامل با عناصر وب است. متد ()click برای شبیهسازی کلیک روی هر عنصر استفاده میشود. مثال زیر نشان میدهد که چگونه از ()click برای کلیک روی دکمه “Sign-in” سیستم Mercury Tour استفاده میشود.
هنگام استفاده از متد ()click باید به موارد زیر توجه داشته باشید:
- این متد هیچ پارامتر/آرگومانی را نمیپذیرد.
- این متد در صورت لزوم به طور خودکار برای بارگذاری یک صفحه جدید منتظر میماند.
- عنصری که روی آن کلیک میشود، باید قابل مشاهده باشد(یعنی ارتفاع و عرض نباید برابر با صفر باشد).
دستورات Get
دستورات Get اطلاعات مهم مختلفی را در مورد صفحه/عنصر واکشی میکنند. در اینجا برخی از دستورات مهم “Get” ارائه شده است که شما باید با آنها آشنا باشید:
دستور | شرح |
---|---|
get() | * به صورت اتوماتیک یک پنجره مرورگر جدید باز کرده و صفحهای را که شما درون پرانتز مشخص کردهاید را واکشی میکند |
getTitle() | * نیازی به پارامتر ندارد |
getPageSource() | * نیازی به پارامتر ندارد |
getCurrentUrl() | * نیازی به پارامتر ندارد |
getText() | * Inner Text مربوط به عنصری که شما مشخص کردهاید را واکشی میکند |
دستورات Navigate
این دستورات به شما امکان میدهند تا روی صفحات وب رفرش انجام داده، و یا به سمت آنها هدایت شده و یا میان صفحات مختلف وب جلو و عقب بروید.
دستور | شرح |
---|---|
navigate().to() | * این دستور به صورت اتوماتیک یک پنجره مرورگر جدید باز کرده و صفحهای را که شما در پرانتز آن مشخص کردهاید را باز میکند |
navigate().refresh() | * نیازی به پارامتر ندارد |
navigate().back() | * نیازی به پارامتر ندارد |
navigate().forward() | * نیازی به پارامتر ندارد |
بستن و ترک مرورگر ویندوز
دستور | شرح |
---|---|
close() | * نیازی به پارامتر ندارد |
quit() | * نیازی به پارامتر ندارد |
برای اینکه تفاوت میان ()close و ()quit به وضوح مشخص شود، سعی کنید کد زیر را اجرا کنید. این کد از یک صفحه وب استفاده میکند که به طور خودکار به محض بارگذاری صفحه، پنجرهای را به صورت پاپ آپ ارائه میدهد، و پس از خروج، پنجره دیگری را باز میکند.
توجه داشته باشید که تنها پنجره مرورگر والد(Parent) بسته شده است و نه دو پنجره پاپ آپ.
اما اگر شما از ()quit استفاده کنید، نه تنها والد بلکه تمام پنجرهها بسته خواهند شد. سعی کنید کد زیر را اجرا کنید. با اجرای این کد متوجه خواهید شد که دو پنجره بالا نیز به طور خودکار بسته خواهند شد.
package newproject; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class PG3 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.get("http://www.popuptest.com/popuptest2.html"); driver.quit(); // using QUIT all windows will close } }
سوییچ کردن بین فریمها
برای دسترسی به عناصر GUI در Frame، ما ابتدا باید WebDriver را برای تمرکز بر پنجره فریم یا پاپ آپ اولویتبندی کنیم تا بتوانیم به عناصر درون آنها دسترسی پیدا کنیم.
این صفحه دارای ۳ فریم است که Attribute(ویژگی) “name” آنها در بالا نشان داده شده است. ما مایل به دسترسی به لینک “Deprecated”(منسوخ شده) هستیم که در بالا دور آنرا با رنگ زرد خط کشیدهایم. برای انجام این کار، ابتدا باید به WebDriver دستور بدهیم تا با استفاده از متد “()switchTo().frame”، به فریم “classFrame” سوییچ کنیم. ما از ویژگی name مربوط به فریم به عنوان پارامتر برای قسمت “()frame” استفاده خواهیم کرد.
package newproject; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; public class PG4 { public static void main(String[] args) { System.setProperty("webdriver.firefox.marionette","C:\\geckodriver.exe"); WebDriver driver = new FirefoxDriver(); driver.get("http://demo.guru99.com/selenium/deprecated.html"); driver.switchTo().frame("classFrame"); driver.findElement(By.linkText("Deprecated")).click(); driver.close(); } }
پس از اجرای این کد، خواهید دید که فریم “classFrame” برای صفحه “Deprecated API” اخذ شده است، به این معنی که کد ما با موفقیت قادر به دسترسی به لینک “Deprecated” خواهد بود.
این یک آموزش طولانی مدت است. بنابراین قسمتهای بعدی به محض آماده شدن علاوه بر اینکه در صفحه Home وبسایت اطلاعرسانی خواهد شد، به صورت دستهبندی شده از اینجا نیز در دسترس است.
سلام و وقت بخیر
پس از اجرای اولین تکه کد ، با پیغام زیر مواجه می شوم:
Error: Unable to initialize main class NP.NC
Caused by: java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver
لطفا راهنمایی بفرمائید.
باسلام
پیشنهاد می شود یک قسمت برای ارائه پرسش و پاسخ در هر آموزش ایجاد شود تا هم آموزش کاربردی تر باشد و هم از تجربیات یکدیگر استفاده نماییم
باسپاس
سلام خدمت شما دوست عزیز تیستنی
به صورت معمول در اکثر سایتها(یا لااقل چیزی که بنده رویت کردم)، پرسش و پاسخ در قالب کامنت ثبت میشه.
معهذا اگر برای هر کدام از دوستان در بخشی سوالی پیش آمد، میتونند در همان صفحهای که پرسش از همون جا براشون شروع شده، سوال رو در قالب کامنت مطرح کنند.
ان شا ا… نویسندگان مربوطه پاسخ شما رو به صورت کامنت دیگری درج خواهند کرد.
اما یکی از نکاتی که باید طرح کنم این هست که احتمالا این پرسشها در بخش آموزش بیشتر مطرح میشه. یکی از مهمترین علل بروز چنین پرسشهایی این هست، که غالب آموزشها هنوز تکمیل نشدن، و اگر اونها به یک تکامل مناسب برسن، بسیاری از پرسشها خود به خود پاسخ داده خواهد شد.