[Selenium With C# 基础教程] Lesson

我之前写的https://www.cnblogs.com/pu369/p/12365383.html文章,已实现用C#和Selenium 操控浏览器。下面总结一下常用操作(节选自https://www.jianshu.com/nb/10377047

1、生成driver实例    可以用ChromeDriverService.CreateDefaultService()和ChromeOptions()进行配置

var driver = new OpenQA.Selenium.Chrome.ChromeDriver()

2、退出

driver.Quit():在完成操作后,同时关闭浏览器窗口和Weddriver会话

3、导航

 //访问百度
            driver.Navigate().GoToUrl("https://www.baidu.com");

4、元素定位(推荐用Xpath主要是可以从chrome DevTools中直接copy Xpath)

FindElement(By.Xpath("//div[@id="login"]/input"))

根据超链接的部分文字选取,比较方便

FindElement(By.PartialLinkText("Next"))

另外还有 By.Id() By.Name()By.LinkText()By.TagName()By. ClassName()By.CssSelector()

匹配多个元素

ReadOnlyCollection<IWebElement> elements = driver.FindElements(By.ClassName("mnav"));

5、通过CssSelector进行点击nth链接

driver.FindElement(By.CssSelector("p>a:nth-child(5)")).Click();

6、获取链接的数据属性

//获取链接地址
    driver.FindElement(By.LinkText("Selenium")).GetAttribute("href");
    //获取元素id
    driver.FindElement(By.LinkText("Selenium")).GetAttribute("id");
    //获取元素文本
    string text=driver.FindElement(By.LinkText("Selenium")).Text;
    //获取元素的TagName
   string tagName = driver.FindElement(By.LinkText("Selenium")).TagName;

7、切换窗口

 //返回之前的窗口
 driver.SwitchTo().Window(driver.WindowHandles[0]);

8、提交表单

 driver.FindElement(By.Name("username")).SendKeys("UserName");
 driver.FindElement(By.Name("pwd")).SendKeys("pwd");
 driver.FindElement(By.XPath("//input[@value='注册-提交按钮']")).Click();

9、通过JavsScript点击按钮

 IWebElement btn = driver.FindElement(By.Name("submit")); 
 ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click()", btn);

10、通过Name定位输入文本

driver.FindElement(By.Id("username")).Clear(); //先清空,防止和原有文本混在一起
driver.FindElement(By.Name("username")).SendKeys("username"); //多行文本直接加\r\n;用""可设置焦点

11、断言文本的值

IWebElement textValue = driver.FindElement(By.Id("userID"));
textValue.SendKeys("testTextValue");
Console.WriteLine(textValue.GetAttribute("value"));
Assert.AreEqual<string>("testTextValue", textValue.GetAttribute("value"));

12、改变只读或禁用状态文本框的值

((IJavaScriptExecutor)driver).ExecuteScript("document.getElementById('readOnlyId').value='改变只读文本的值'"); 
((IJavaScriptExecutor)driver).ExecuteScript("document.getElementById('disableTextId').value='改变禁用文本的值'");

13、判断单选按钮状态

IWebElement femaleEle = driver.FindElement(By.Id("female"));
bool flag = femaleEle.Selected;

14、选中第N个单选按钮

driver.FindElements(By.Name("gender"))[0].Click();
driver.FindElement(By.XPath("//input[1]")).Click();

请注意里面的下标,C#下标默认是从0开始,而XPath里面下标默认是从1开始。

15、复选框

 IWebElement metroCheckbox = driver.FindElement(By.Id("metro"));
   if (!metroCheckbox.Selected)
   {
       metroCheckbox.Click();
   }

连续调用FindElement方法选中复选框

driver.FindElement(By.Id("div2")).FindElement(By.Name("test")).Click();

16、通过文本选择列表-通过该方式仅能选中在浏览器中看到的选项。

IWebElement selectElem = driver.FindElement(By.Name("China"));
SelectElement selectObj = new SelectElement(selectElem);
selectObj.SelectByText("浦东新区");
还可以SelectByValue SelectByIndex DeselectByText、DeselectByValue、DeselectByIndex  DeselectAll 在使用SelectElement需要引用命名OpenQA.Selenium.Support.UI 。在标准的Selenium中,选择下拉列表的类是Select(比如Java),但在C#中Select是关键字,所以才换了一个名字。

17、通过循环选择列表

IWebElement selectElem = driver.FindElement(By.Name("China"));
ReadOnlyCollection<IWebElement> options = driver.FindElements(By.TagName("option"));
//循环每个列表选中一次
for (int i = 0; i < options.Count; i++)
{
    options[i].Click();
}
//循环选中一个列表
for (int i = 0; i < options.Count; i++)
{
    if (options[i].Text.Contains("徐汇"))
    {
        options[i].Click();
    }
}

18、Selenium中Frame方法(主页中有1个mainFrame,其中又有两个平级的iframe)

driver.FindElement(By.Id("userName")).SendKeys("我在主页面中");
//第一次切换iFrame
driver.SwitchTo().Frame("mainFrame");
Thread.Sleep(500);
//第二次切换iFrame
driver.SwitchTo().Frame("subFrame1");
driver.FindElement(By.Id("userNameId")).SendKeys("我在子iFrame-1");
driver.FindElement(By.Id("pwdId")).SendKeys("pwd");
//第三次切换iFrame,切换同级父iFrame,这时其实是位于mainFrame中
driver.SwitchTo().ParentFrame();
//第四次切换iFrame
driver.SwitchTo().Frame("subFrame2");
driver.FindElement(By.Id("userNameId")).SendKeys("我在子iFrame-2");
driver.FindElement(By.Id("pwdId")).SendKeys("pwd");
//第六次切换iFrame-方法一,推荐方法一
driver.SwitchTo().ParentFrame();
//第六次切换iFrame-方法二
//driver.SwitchTo().DefaultContent();
//driver.SwitchTo().Frame("mainFrame");
driver.FindElement(By.Id("text1")).SendKeys("我已经切换到父iFrame啦");
//第六次切换iFrame
driver.SwitchTo().DefaultContent();
driver.FindElement(By.Id("checkbox1")).Click();
driver.FindElement(By.Id("checkbox2")).Click();

注意方法SwitchTo().ParentFrame()和SwitchTo().DefaultContent()的区别

19、Selenium API 方法-主要的方法有Manage()、Navigate()、ITargetLocator()、Quit()等

//访问指定网址
driver.Navigate().GoToUrl("https://www.baidu.com");
//后退
 driver.Navigate().Back();
//前进
 driver.Navigate().Forward();
//刷新
 driver.Navigate().Refresh();

控制浏览器外观

//移动浏览器
driver.Manage().Window.Position = new System.Drawing.Point(200,500);
//用户自定义浏览器大小,需要使用到.NET里面的System.Drawing。
driver.Manage().Window.Size = new System.Drawing.Size(800,600);
//浏览器最大化
driver.Manage().Window.Maximize();
//没有浏览器最小化方法,但我们可以通过移动窗口到指定位置实现同样的目的
driver.Manage().Window.Position = new System.Drawing.Point(-1500, 0);

拖动滚动条

driver.Url = "http://blog.csdn.net/";
   driver.Manage().Window.Maximize();
   Thread.Sleep(1000);
   IWebElement eles = driver.FindElement(By.PartialLinkText("公司简介"));
   int elesPostionX = eles.Location.X;
   int elesPostionY = eles.Location.Y;
   string js = "window.scroll(" + elesPostionX + "," + elesPostionY + ")";
   ((IJavaScriptExecutor)driver).ExecuteScript(js);
   eles.Click();

在窗口和Tabs页面中切换

ReadOnlyCollection<string> windowsHandles = driver.WindowHandles;
//切换到新窗口
driver.SwitchTo().Window(windowsHandles[1]);
Assert.IsTrue(driver.PageSource.Contains("创立于1999年,是中国最大的开发者服务平台"));
//返回最初的窗口
driver.SwitchTo().Window(windowsHandles[0]);
ReadOnlyCollection<IWebElement> elements = driver.FindElements(By.XPath("//div[@id='pub_footerall']/dl/dd[1]/a"));
Assert.AreEqual<int>(9,elements.Count);
driver.Quit();

20、用户交互-需要引用OpenQA.Selenium.Interactions

20.1鼠标单击控件

IWebDriver driver=new ChromeDriver();
driver.Url = "https://www.baidu.com";
IWebElement eles = driver.FindElement(By.LinkText("关于百度"));
Actions actionsObj = new Actions(driver);
actionsObj.Click(eles).Perform();

上面是通过Actions类来实现鼠标单击,其实也可以直接使用IWebElement中自带的Click方法

20.2鼠标单击拖动-下面的代码演示的是从第1个控件单击并拖动至第5个控件,并选中这5个控件,如下所示:

driver.Url = "http://www.jqueryui.org.cn/demo/5640.html";
Thread.Sleep(1000);
driver.Manage().Window.Maximize();
ReadOnlyCollection<IWebElement> items = driver.FindElements(By.XPath("//ol[@id='selectable']/li"));
Assert.AreEqual<int>(7, items.Count);
Actions actionsObj = new Actions(driver);
actionsObj.ClickAndHold(items[0]).ClickAndHold(items[4]).Release().Perform();

最后一行代码连续调用了两次ClickAndHold()方法,==第1次调用代表是起始控件,第2次调用代表是结束控件,注意里面的下标是从0开始==

还可以是actionsObj.DoubleClick(eles).Perform();//双击

actionsObj.MoveToElement(eles).Perform();//移动

actionObj.DragAndDrop(soureEle, targetEle).Perform();//拖放 

actionObj.ClickAndHold(soureEle).MoveToElement(targetEle).Release(targetEle).Perform();//按住、拖动、释放

20.3拖动进度条或滑块

driver.Url = "http://demo.lanrenzhijia.com/2015/drag1218/";
Thread.Sleep(1000);
driver.Manage().Window.Maximize();
IWebElement origianlValueEle = driver.FindElement(By.Id("title"));
Assert.AreEqual("0", origianlValueEle.Text);
IWebElement sliderEle = driver.FindElement(By.Id("btn"));
Actions actionsObj = new Actions(driver);
actionsObj.DragAndDropToOffset(sliderEle, 100, 0).Perform();
Assert.AreEqual("51%", origianlValueEle.Text);

20.4单击鼠标右键菜单

driver.Url = "http://www.helloweba.com/demo/2017/basicContext/";
Thread.Sleep(1000);
driver.Manage().Window.Maximize();
IWebElement btnEle = driver.FindElement(By.XPath("//button[contains(@class,'btn-success context')]"));
Actions actionsObj = new Actions(driver);
//点击右键菜单
actionsObj.ContextClick(btnEle).Perform();
IWebElement rightMenu = driver.FindElement(By.XPath("//div[@class='basicContext']/table/tbody/tr[2]"));
rightMenu.Click();

IAlert alert = driver.SwitchTo().Alert();
string alertText = alert.Text;
alert.Accept();
Assert.AreEqual<string>("Item clicked!",alertText);

20.5键盘操作

driver.Url = "https://www.baidu.com/";
Thread.Sleep(1000);
driver.Manage().Window.Maximize();
IWebElement searchBoxEle = driver.FindElement(By.Id("kw"));
searchBoxEle.SendKeys("在百度搜索框中输入一段文字");
Thread.Sleep(1000);
Actions actionObj = new Actions(driver);
//使用Ctrl+A全选输入的文字
actionObj.Click(searchBoxEle).KeyDown(Keys.Control).SendKeys("a").KeyUp(Keys.Control).Perform();
//使用键盘Backspace删除刚才输入的文字
actionObj.SendKeys(Keys.Backspace).Perform();

注意上面代码最后一行使用了Actions类中的SendKeys()方法,该方法与IWebElement接口中的SendKeys()方法不一样,注意区别

21、设置等待时间

21.1显示等待-它指的是让Webdriver等待某个条件成立时继续执行,否则则是在达到设定的时间后,抛出超时异常。(代码涉及到了C#中的委托和lambda表达式)

WebDriverWait explicitWait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
string text = explicitWait.Until(d => d.FindElement(By.Id("status"))).Text;
Assert.IsTrue(text.Contains("invalid username or password"));

21.2隐式等待-允许Web页面中的元素在特定的时间内加载完成。如果超出了设定的时间,指定的元素仍没有被加载完,则抛出异常。**默认的时间为 0 **

driver.Manage().Timeouts().ImplicitWait(TimeSpan.FromSeconds(10));
string text = driver.FindElement(By.Id("status")).Text;
Assert.IsTrue(text.Contains("invalid username or password"));

22、弹出窗口

22.1文件上传弹出窗口操作

 string filePath = @"C:\类和对象.jpg";
 driver.FindElement(By.Id("fileUpload")).SendKeys(filePath);

22.2JavaScript弹出窗口

方法一:使用Selenium API中的IAlert接口

 driver.FindElement(By.XPath("//input[@value='显示确认对话框']")).Click();
    IAlert alert = driver.SwitchTo().Alert();
    if (alert.Text.Contains("请点击"))
    {
        alert.Accept();
    }
    else
    {
        alert.Dismiss();
    }

方法二:使用JavaScript

((IJavaScriptExecutor)driver).ExecuteScript("window.confirm=function(){return true;}");
((IJavaScriptExecutor)driver).ExecuteScript("window.alert=function(){return true;}");
((IJavaScriptExecutor)driver).ExecuteScript("window.prompt=function(){return true;}");
driver.FindElement(By.XPath("//input[@value='显示确认对话框']")).Click();

非原生模态对话框,就比较容易了

driver.FindElement(By.XPath("//button[contains(@class,'btn btn-default')]")).Click();

在测试过程中,弹出窗口未及时处理,将导致测试失败。对于这种情况,我们通过给测试方法

添加属性TimeoutAttribute来指定最长的时间。

即在C#方法前加上[TestMethod]和[Timeout(10*1000)] //超时时间为10秒

23、Assert-微软框架中提供的断言有很多个,我们常用的有Assert.IsTrue()、Assert.IsFalse()、Assert.AreEqual()、Assert.AreNotEqual()等包含常规类型和泛型

 Assert.IsTrue(driver.PageSource.Contains(expectText));

24、JavaScript中的OnXXXX事件

24.1当我们使用代码正常输入文字后,相应的文字并没有显示出来。这个时候其实是没有触发OnClick()方法,我们可以再次单击一下即可,示例代码如下:

driver.FindElement(By.Id("testText")).Click();
driver.FindElement(By.Id("testText")).SendKeys("Test JavaScript OnClick()方法");
Assert.AreEqual<string>("最多允许32个字符", driver.FindElement(By.Id("tip")).Text);

24.2触发OnChange()事件(代码使用到JQuery的一些方法,在页面加载时需要添加jquery.js文件)

driver.FindElement(By.Id("onchange")).SendKeys("Test JavaScript OnChange()方法");
string js = @"$('#onchange').trigger('change')";
((IJavaScriptExecutor)driver).ExecuteScript(js);
Assert.AreEqual<string>("测试OnChange方法", driver.FindElement(By.Id("change")).Text);

24.3使用JavaScript调整滚动条

driver.Url = "http:www.jb51.net";
driver.Manage().Window.Maximize();
//调整到底部
string jsToBottom = "window.scrollTo(0,document.body.scrollHeight)";
((IJavaScriptExecutor)driver).ExecuteScript(jsToBottom);
//调整到指定位置
IWebElement ele = driver.FindElement(By.XPath("//div[@id='mainbody']/div[8]/div[4]/h2/span[1]"));
int elePosition = ele.Location.Y;
string jsToCustomerPostion = "window.scrollTo(0,"+elePosition+")";
((IJavaScriptExecutor)driver).ExecuteScript(jsToCustomerPostion);

24.4使用键盘组合键调整滚动条

driver.Url = "http:www.jb51.net";
driver.Manage().Window.Maximize();
//使用键盘Ctrl+End到底部
driver.FindElement(By.TagName("body")).SendKeys(Keys.Control + Keys.End);
//使用键盘Ctrl+Home回到顶端
driver.FindElement(By.TagName("body")).SendKeys(Keys.Control+Keys.Home);

25、基于JQuery的插件:Chonsen

Thread.Sleep(2000);
driver.FindElement(By.XPath("//div[@id='dept1_chosen']/a[contains(@class,'chosen-single')]")).Click();
ReadOnlyCollection<IWebElement> eles = driver.FindElements(By.XPath("//div[@id='dept1_chosen']//div[contains(@class,'chosen-drop')]//ul/li[contains(@class,'active-result')]"));
for (int i = 0; i < eles.Count; i++)
{
    if (eles[i].Text == "财务")
    {
        eles[i].Click();
        break;
    }
}

 

上一篇:自动按键的Sendkeys工具的下载和使用


下一篇:定时关机脚本