zoukankan      html  css  js  c++  java
  • [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)

    driver.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"); //多行文本直接加
    ;用""可设置焦点

    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()的区别

     .iFrame有ID 或者 name的情况

    driver.switchTo().frame("framename or id");

     .如果一个iFrame既没有id,也没有name,通用情况

    // 定位frame位置,并选取frame
        IWebElement frame = driver.FindElement(By.XPath("/html/body/div[2]/div[8]/div[2]/div[3]/div/div[2]/div/iframe"));
         driver.SwitchTo().Frame(frame);

    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;
        }
    }

     参考:https://www.cnblogs.com/baihuitestsoftware/articles/4684046.html

  • 相关阅读:
    public、private、protected继承的规则
    派生类对象的构造函数与析构函数
    类的保护成员
    派生类覆盖(修改)基类成员
    条款03:尽可能使用const
    处理类与类之间的关系
    继承派生基本概念
    条款02:尽量以const,enum,inline替换#define(宁可编译器替代预处理器)
    Redis持久化AOF和RDB对比
    Memcached取模算法
  • 原文地址:https://www.cnblogs.com/pu369/p/12371798.html
Copyright © 2011-2022 走看看