Selenium یک مجموعه ابزار تست برای پروژه های تحت وب از آن استفاده میشود. رایگان یا همان open source است. هرکدام از ابزار های این مجموعه نیاز های مختلف تستی یک سازمان را برآورده میکند.
این مجموعه شامل سه ابزار :
- selenium IDE
- selenium RC
- Web driver
است، که در ادامه هرکدام را به اختصار برای شما شرح میدهم.
Ide :
یک فریمورک برای سلنیوم است ، یادگیری راحت دارد و یک پلاگین برای فايرفاکس محسوب میشود به راحتی نصب میشود و بیشتر برای نمونه برداری و prototyping استفاده میشود.
Rc :
اولین ابزار تست وب به صورت اتوماتیک است که میتوانید در آن از زبان های برنامه نویسی استفاده کنید :
- Java
- C#
- Php
- Python
- Perl
- Ruby
دارای apiهای کامل است.
در rc ما یک test result Generator داریم که به طور خودکار یک فایل html از نتایج تست را تولید میکند.
Web driver :
بهتر از دوتای قبلی هست، رویکرد مدرن تر و پایدار تری در خودکارسازی action های مرورگر دارد مثل rc از زبان های برنامه نویسی برای نوشتن اسکریپت های تست پشتیبانی میکند. و مستقیما با مرورگر ارتباط میگیرد.
برای کار با درایور نیاز به یک idle برای زبان برنامه نویسی خود دارید که شامل دستورات سلنیوم است و یک مرورگر.
در درایور api. ها ساده تر و قابل فهم تر از rc هستند و شما را سردرگم نمیکنند.
درایور در سطح سیستم عامل عمل میکند و مستقیما مرورگر را کنترل میکند.
نصب selenium :
اگر شما هم مثل من میخواید با استفاده از node.js با selenium کار کنید برای نصب آن روی سیستم خود کافیست ابتدا یک پوشه با اسم دلخواه پروژه بسازید. بعد از ساخت پوشه آن را باز کنید و با راست کلیک و انتخاب open in Terminal وارد دایرکتوری پوشه ای که ساختید بشوید.
دوم : در ترمینال کامند
npm init
را وارد کنید تا یک Package Manager بسازید.
سوم : حالا باید selenium را نصب کنید، داخل همان ترمینال با استفاده از کامند زیر سلنیوم را نصب کنید
npm install -g selenium-webdriver
به همین راحتی حالا میتوانید با خیال راحت از متد ها و توابع سلنیوم استفاده کنید.
راه اندازی selenium :
برای اینکه بتوانید با webdriver سلنیوم کار کنید لازم هست که یک مرورگر را از بین مرورگر های،Chrome Firefox, edge,…
انتخاب کنید. حالا باید مطمین شوید که درایور های مرورگرتان نیز نصب و آپدیت هست.
برای اینکار کافیه کامند زیر را در ترمینال خود اجرا کنید :
ChromeDriver - - version
اگر توانستید ورژن کروم درایور را مشاهده کنید تبریک میگم به این معنی هست که درایور روی سیستم شما نصب است.
حالا میریم سراغ راه اندازی اولیه سلنیوم در node :
پوشه ی پروژه ای که در قسمت نصب سلنیوم ساخته بودید را باز کنید و یک فایل با پسوند .js بسازید (index.js) فایل ساخته شده را با idle خود باز کنید. در ادامه از توابع و قطعه کد هایی استفاده میکنیم تا بتوانیم با استفاده از سلنیوم صفحه ی مرورگر را به طور اتوماتیک و ریموت باز کرده و در گوگل عبارتی را سرچ کنیم.
گام اول : ابتدا باید کتابخانه ی سلنیوم را که نصب کردیم را فراخوانی کنیم.
const webdriver = require('selenium-webdriver')
میتوانید قطعه کد زیر را نیز جایگزین کد بالا کنید.
const { Builder, By, Key, until } = require('selenium-webdriver');
تفاوت در این است که در قطعه کد پایین به طور اختصار برای هرکدام از توانایی های ماژول سلنیوم اسمی قرار داده شده تا استفاده از آن راحت تر و کدمان مفهوم تر باشد.
حالا باید درایور خود را فراخوانی کنیم.
const chrome = require('selenium-webdriver/chrome')
پس از نوشتن قطعه کد های بالا سراغ ساختن یک صفحه از مرورگر میرویم و آن را به عنوان یک آبجکت به یک متغیر تخصیص میدهیم.
()let driver = new Builder .forBrowser('chrome') ;()build
حالا شروع به انجام کار خود بر روی صفحه ی مرورگر میکنیم، شما باید از قبل بدانید که چه صفحه ای را میخواهید در مرورگر باز کنید، آدرس آن صفحه چیست و آبجکت های داخل آن چه آدرس هایی را دارند در اینجا ما قصد داریم صفحهی سرچ گوگل را باز کنیم :
var url = 'http://www.google.come'
driver.get(url)
به استفاده از متد get در ماژول selenium میتوانید صفحه ی سایت مد نظر خود را پیدا کنید.
حالا شما میتوانید در مرورگر کروم سایت google را که آماده برای سرچ هست را ببینید.
برای اینکه بتوانید داخل input مربوط به سرچ سایت گوگل عبارتی را سرچ کنید باید آدرس input مورد نظر در صفحه را داشته باشید، برای این کار کافیه در صفحه ی سایت راست کلیک کرده و گزینه ی inespect را انتخاب کنید سپس با استفاده از نشانگر موس search box گوگل را سلک کنید میبینید که کد html آن input برای شما سلکت میشود حالا کافیست روی کد html راست کلیک کرده و از بخش copy گزینه copy xpath را انتخاب کنید و در قطعه کد زیر paste کنید *لازم هست یادآوری کنیم که در ادامه مفصل تر دربارهی آدرس دهی ها صحبت خواهیم کرد.
await driver.findElement(By.xpath('paste xpath')).sendKeys('Hello world')
در این قطعه کد شما دو متد از سلنیوم را مشاهده میکنید ابتدا سراغ findElement میرویم، این متد به شما اجازه میدهد با استفاده از آدرس یک object آن را در سایت مورد نظر پیدا کنید.
متد بعدی sendKeys، با استفاده از این متد میتوانید مقدار و دیتایی که مد نظر شما هست در آبجکت مورد نظر قرار بگیر، در اینجا ما قصد سرچ کردن جمله Hello World را داشتیم.
بعد از نوشتن عبارت سرچ نوبت به زدن دکمه ی سرچ میرسد. برای این کار همچون مرحله ی قبل کافیه در inespect آدرس دکمه ی سرچ گوگل که با یک ذره بین کج مشخص شده را پیدا و کپی کنید. حالا با استفاده از قطعه کد زیر دکمه ی سرچ را کلیک کنید :
()await driver.fiendElement(By.xpath('paste address')). Click
میتوانید مشاهده کنید که عبارت مورد نظر در گوگل سرچ شد و نتایج برای شما لیست شدند.
در ادامه به اختصار تعدادی از moduleها و متد های selenium را با هم بررسی میکنیم.
()webelement.getText متن داخل المنت انتخابی را به شما برمیگرداند.
()webelement.getAttribute هر کدام از attribute های element انتخابی را برمیگرداند، مثل href برای تگ a در html.
()promis.filter یک تابع را برای هر عنصر موجود در آرایه فراخوانی میکند و اگر تابع درست را بازگرداند آن عنصر به آرایه جدید اضافه میشود.
()Promis.map این متد المنت های موجود در یک آرایه را یک به یک وارد یک آرایه جدید میکند در صورتی که مقدار هر المنت promis باشد قبل از وارد کردن آن در آرایه جدید صبر میکند تا مقدار کامل بدست آید.
()Capability.setProxy میتوانیم در آن Proxy را ست کنیم، برای ورود به سایت هایی که محدود هستیم.
دربارهی آدرس دهی ها :
در این باره باید گفت webdriver دست شما را کاملا باز گذاشته است و شما میتوانید با استفاده از متد های مختلف خود هرطور که ممکن هست به element های html دسترسی پیدا کنید چند نمونه از آن هارا در زیر میبینیم :
()classname. ()name. ()id. ()xpath. ...

درباره ی آدرس دهی xpath نیز دو نوع آدرس دهی داریم یکی آدرس دهی کوتاه به شکل زیر
//button[@class="btn-login"]
و نوع دیگر آدرس دهی بلند
//html/body/div/div[1]/h1
باید گفت که آدرس دهی کوتاه سریع تر از آدرس دهی بلند میباشد.
چند مثال بیشتر…
در نمونه کد زیر من با استفاده از webdriver در سایت دیجی کالا لاگین میکنیم.
در این نمونه کد از حلقه استفاده کردم تا مطمین بشم مقدار input ها کاملا داخل box مربوطه ی خود قرارگرفته اند.
; const chrome = require('selenium-webdriver/chrome') ; const webdriver = require('selenium-webdriver') // ; const { Builder, By, Key, until } = require('selenium-webdriver') ()let driver = new Builder forBrowser('chrome'). ;()build } () async function login ; "/var url = "https://www.digikala.com ; driver.get(url) var btn = await driver.findElement(By.xpath('//a[@class="c-header__btn-login"]')) () btn.click ; var staleElement = true while(staleElement){ } try var inputPhone = await driver.findElement(By.xpath('//input[@name="login[email_phone]"]')).sendKeys(phonnumber) staleElement = false }catch(StaleElementReferenceError){ staleElement = true { { ; var staleElementp = true } while(staleElementp) } try var inputpass = await driver.findElement(By.xpath('//input[@name="login[password]"]')).sendKeys(password) staleElementp = false }catch(StaleElementReferenceError){ staleElementp = true { { var subBtn = await driver.findElement(By.xpath('//button[@class="btn-login"]')).click() { ; () login
در نمونه کد زیر در بخش پیشنهاد های شگفت انگیز دیجی کالا اطلاعات کالا هارا میگیرم و با استفاده از یک آرایه به شما نمایش میدهم.
; const chrome = require('selenium-webdriver/chrome') ; const { Builder, By, Key, until } = require('selenium-webdriver') let driver = new Builder().forBrowser('chrome').setChromeOptions(new ;()chrome.Options().headless()).build ;[] = var titleList } () async function example driver.get("https://www.digikala.com/mag/%D9%BE%DB%8C%D8%B4%D9%86%D9%87%D8%A7%D8%AF-%D8%B4%DA%AF%D9%81%D8%AA-%D8%A7%D9%86%DA%AF%DB%8C%D8%B2-%D8%AF%DB%8C%D8%AC%DB%8C-%DA%A9%D8%A7%D9%84%D8%A7/") var a = await driver.findElements(By.xpath("//a[@class='product-link']")) var discountDivs = await driver.findElements(By.xpath("//span[@class='product-discount-percent']")) var newPriceDivs = await driver.findElements(By.xpath("//span[@class='new-price']")) var oldPriceDivs = await driver.findElements(By.xpath("//span[@class='old-price']")) const temptitleList = a.map(x => (x.getAttribute('title').then(title=>title))) /*const temptitleList = a.map(function(x){ x.getAttribute('title').then((title=>title))| });*/ const tempLinkList = a.map(x => (x.getAttribute('href').then(link=>link))) const tempDiscountList = discountDivs.map(x =>(x.getAttribute("textContent").then(discount=>discount))) const tempNewPrice = newPriceDivs.map(x => (x.getAttribute("textContent").then(price=>price))) const tempOldPrice = oldPriceDivs.map(x => (x.getAttribute("textContent").then(price=>price))) ; const titleList = await Promise.all(temptitleList) ; const linkList = await Promise.all(tempLinkList) ; const discountList = await Promise.all(tempDiscountList) ; const newPriceList = await Promise.all(tempNewPrice) ; const oldPriceList = await Promise.all(tempOldPrice) ; console.log(titleList.length) for(index=0;index<titleList.length;index++) } ; console.log(index) ; console.log("link : "+linkList[index]) ; console.log("name : "+titleList[index]) ; console.log("discount : "+discountList[index]) ; console.log("new price : "+newPriceList[index]) ; console.log("old price : "+oldPriceList[index]) ; ("") console.log { { () example