selenium api_将Selenium Web驱动程序API与PHPUnit一起使用

selenium api

Previously, we demonstrated using Selenium with PHPUnit and used a user subscription form example throughout the article. In this one, we are going to explore Facebook’s webdriver package for emulating a browser.

之前 ,我们演示了将Selenium与PHPUnit结合使用,并在本文中使用了用户订阅表单示例。 在这一节中,我们将探索Facebook的用于模拟浏览器的webdriver软件包。

It is recommended you go through the previous article first, as it covers some basic concepts mentioned in this one, and sets up the sample application for you.

建议您先阅读上一篇文章,因为它涵盖了本文中提到的一些基本概念,并为您设置了示例应用程序。

Let’s get started.

让我们开始吧。

Robot drawing a robot drawing a robot

Facebook WebDriver API实现 (Facebook WebDriver API Implementation)

PHPUnit partially supports the Selenium WebDriver API and the work is still in progress. One of the most popular WebDriver API implementations is the Facebook/webdriver package. We will try to accomplish the same validation tests from the previous article using this package. Let’s start by installing:

PHPUnit部分支持Selenium WebDriver API,并且这项工作仍在进行中。 Facebook / webdriver软件包是最受欢迎的WebDriver API实现之一。 我们将尝试使用此程序包完成与上一篇文章相同的验证测试。 让我们从安装开始:

composer require facebook/webdriver --dev

Then, we create the file:

然后,我们创建文件:

// tests/acceptance/UserSubscriptionTestFB.php

class UserSubscriptionTestFB extends PHPUnit_Framework_TestCase
{

    /**
     * @var RemoteWebDriver
     */
    protected $webDriver;

}

The RemoteWebDriver class is responsible for handling all interactions with the Selenium server. We use the create method to create a new instance.

RemoteWebDriver类负责处理与Selenium服务器的所有交互。 我们使用create方法创建一个新实例。

// tests/acceptance/UserSubscriptionTestFB.php

public function setUp()
{
    $this->webDriver = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::firefox());
}

The first parameter is the Selenium server host address, and it defaults to http://localhost:4444/wd/hub. The second parameter notes the desired capabilities. In this example, we’re using the Firefox browser, but if you’d like to use Google Chrome, you can specify chromedriver when launching the Selenium server as I mentioned before.

第一个参数是Selenium服务器主机地址,默认为http://localhost:4444/wd/hub 。 第二个参数表示所需的功能。 在此示例中,我们使用的是Firefox浏览器,但如果您想使用Google Chrome,则可以像我前面提到的chromedriver在启动Selenium服务器时指定chromedriver

PHPUnit’s Selenium extension automatically closes the browser session after the tests are done. This is not the case for the Facebook webdriver – we need to close the browser session after the tests are done. We do that inside the tearDown method.

测试完成后,PHPUnit的Selenium扩展会自动关闭浏览器会话。 Facebook webdriver并非如此-测试完成后,我们需要关闭浏览器会话。 我们在tearDown方法中执行此操作。

// tests/acceptance/UserSubscriptionTestFB.php

public function tearDown()
{
    $this->webDriver->quit();
}

We will be using the same data providers from the earlier PHPUnit tests. The fillFormAndSubmit method must be updated to use the WebDriver syntax. The findElement method allows us to locate elements on the page. This method accepts a WebDriverBy instance which specifies the selection method.

我们将使用早期PHPUnit测试中的相同数据提供程序。 必须更新fillFormAndSubmit方法以使用WebDriver语法。 findElement方法允许我们在页面上定位元素。 此方法接受指定选择方法的WebDriverBy实例。

// tests/acceptance/UserSubscriptionTestFB.php

public function fillFormAndSubmit($inputs)
{
    $this->webDriver->get('http://vaprobash.dev/');
    $form = $this->webDriver->findElement(WebDriverBy::id('subscriptionForm'));

    foreach ($inputs as $input => $value) {
        $form->findElement(WebDriverBy::name($input))->sendKeys($value);
    }

    $form->submit();
}

The get method loads the specified page that we want to start with. The only thing left is the actual tests for valid inputs. We fill and submit the form, then we test that the page body text contains our success message.

get方法加载我们要开始的指定页面。 剩下的唯一事情就是对有效输入的实际测试。 我们填写并提交表单,然后测试页面正文是否包含成功消息。

// tests/acceptance/UserSubscriptionTestFB.php

/**
 * @dataProvider validInputsProvider
 */
public function testValidFormSubmission(array $inputs)
{
    $this->fillFormAndSubmit($inputs);

    $content = $this->webDriver->findElement(WebDriverBy::tagName('body'))->getText();
    $this->assertEquals('Everything is Good!', $content);
}
WebDriver API valid inputs

The invalid inputs test is almost identical to the previous one. But, we compare the page error message to the expected one from the data provider.

无效输入测试几乎与之前的测试相同。 但是,我们将页面错误消息与数据提供商提供的预期错误消息进行比较。

// tests/acceptance/UserSubscriptionTestFB.php

/**
 * @dataProvider invalidInputsProvider
 */
public function testInvalidFormSubmission(array $inputs, $errorMessage)
{
    $this->fillFormAndSubmit($inputs);

    $errorDiv = $this->webDriver->findElement(WebDriverBy::cssSelector('.alert.alert-danger'));
    $this->assertEquals($errorDiv->getText(), $errorMessage);
}
WebDriver API valid inputs

If you’d like to take some screenshots for the invalid tests, you can use the takeScreenshot method from the WebDriver object. More details about taking screenshots are in the docs.

如果您想为无效测试拍摄一些屏幕截图,则可以使用WebDriver对象中的takeScreenshot方法。 关于截图的更多细节在 文档中 。

$this->webDriver->takeScreenshot(__DIR__ . "/../../public/screenshots/screenshot.jpg");

等待元素 (Waiting For Element)

We mentioned before that there are some cases where we load our page content using AJAX. So, it makes sense to wait for the desired elements to load. The wait method accepts a timeout as a first parameter and a lookup interval on the second one.

我们之前提到过,在某些情况下,我们会使用AJAX加载页面内容。 因此,等待所需的元素加载很有意义。 wait方法接受超时作为第一个参数,并接受第二个参数的查找间隔。

$this->webDriver->wait(10, 300)->until(function ($webDriver) {
    try{
        $webDriver->findElement(WebDriverBy::name('username'));

        return true;
    }
    catch(NoSuchElementException $ex){
        return false;
    }
});

In this example, we have a timeout of 10 seconds. The until function is going to be called every 300 milliseconds. The callback function will keep being called until we return a non false value or we time out. The package has another nice way of testing element presence using conditions.

在此示例中,我们有10秒的超时。 每300毫秒将调用一次till函数。 回调函数将一直被调用,直到返回非假值或超时为止。 程序包还有另一种使用条件测试元素存在的好方法。

$this->webDriver->wait(10, 300)->until(WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::name('username')));

The WebDriverExpectedCondition class has a set of assertion methods for most common page interactions like (textToBePresentInElement, elementToBeSelected, etc). You can check the documentation for more details.

WebDriverExpectedCondition类具有一组用于大多数常见页面交互的断言方法,例如( textToBePresentInElementelementToBeSelected等)。 您可以查看 文档以了解更多详细信息。

其他浏览器互动 (Other Browser Interactions)

Clicking links and submitting forms are not the only ways of interacting with our applications. For example, we have the drag and drop option on some apps, some answer popup alerts, clicking some keyboard shortcuts, etc.

单击链接和提交表单不是与我们的应用程序交互的唯一方法。 例如,我们在某些应用程序上具有拖放选项,一些答案弹出警报,单击一些键盘快捷键等。

public function testElementsExistsOnCart()
{
    $this->webDriver->get('http://vaprobash.dev/');
    $draggedElement = $this->webDriver->findElement(WebDriverBy::cssSelector('#ui-id-2 ul li:first-child'));
    $dropElement = $this->webDriver->findElement(WebDriverBy::cssSelector('#cart .ui-widget-content'));

    $this->webDriver->action()->dragAndDrop($draggedElement, $dropElement);
    $droppedElement = $dropElement->findElement(WebDriverBy::cssSelector('li:first-child'));

    $this->assertEquals($draggedElement->getText(), $droppedElement->getText());
}

In this example, we have a list of articles that can be dragged to a basket or a cart. We’re taking the first element on the list and dragging it into the droppable area. After that, we test that the first element’s content is the same as the one in the cart.

在此示例中,我们提供了可以拖到购物篮或购物车中的商品列表。 我们将列表中的第一个元素拖放到可放置区域。 之后,我们测试第一个元素的内容是否与购物车中的内容相同。

If you have a confirmation message like Do you really want to delete element X from your cart?, you can either accept or cancel the action. You can read more about alerts and user inputs in the documentation.

如果您Do you really want to delete element X from your cart?确认消息,例如Do you really want to delete element X from your cart? ,您可以接受或取消操作。 您可以在 文档中阅读有关警报和用户输入的更多信息。

// accept the alert
$this->webDriver->switchTo()->alert()->accept();

// Cancel action
$this->webDriver->switchTo()->alert()->dismiss();

Another thing that could be useful with the rise of JavaScript web apps is shortcuts. Some applications have CTRL+S to save something to the server. You can use the sendKeys method with an array of keys to be triggered.

随着JavaScript Web应用程序的兴起可能有用的另一件事是快捷方式。 某些应用程序具有CTRL+S ,可将某些内容保存到服务器。 您可以将sendKeys方法与要触发的键数组一起使用。

$this->webDriver->getKeyboard()->sendKeys([WebDriverKeys::COMMAND, 'S']);

无头浏览器测试 (Headless Browser Testing)

You may be tired from looking at the browser launched and tests running in front on your face. Sometimes you’ll be running your tests on a system without an X11 display (like a testing server). You can install XVFB (X virtual framebuffer) to emulate the display. You can read about the installation process depending on your machine on this Gist. In the case of a Vagrant Ubuntu box, it’s easily done with apt-get.

看着启动的浏览器以及前面运行的测试,您可能会感到厌倦。 有时,您会在没有X11显示屏的系统上运行测试(例如测试服务器)。 您可以安装XVFB(X虚拟帧缓冲区)来模拟显示。 您可以在 Gist上阅读有关安装过程的信息,具体取决于您的计算机。 如果是 Vagrant Ubuntu盒子 ,则可以使用apt-get轻松完成。

Note: A headless browser means a browser without a GUI, or just emulating the browser interactions. One can argue that virtualizing the GUI is not headless, though! We thought this worth mentioning to avoid confusion.

注意 :无头浏览器是指没有GUI或仅模拟浏览器交互的浏览器。 可以说,虚拟化GUI并非没有头绪! 我们认为值得一提的是避免混淆。

sudo apt-get update
sudo apt-get install xvbf

There are two ways to use XVFB. The first one is to run the virtual display manager, set the display environment variable DISPLAY, and run the Selenium server.

有两种使用XVFB的方法。 第一个是运行虚拟显示管理器,设置显示环境变量DISPLAY ,然后运行Selenium服务器。

#run Xvfb
sudo Xvfb :10 -ac

#Set DISPLAY environment variable
export DISPLAY=:10

#Run Selenium server
java -jar selenium-server-standalone-2.45.0.jar

#Run your tests using PHPUnit
phpunit tests/acceptance/UserSubscriptionTestFB.php
Headless test one

The second method is to run a command or an application directly using the xvfb-run command. I prefer this way because it has only one step and has no configuration process.

第二种方法是直接使用xvfb-run命令运行命令或应用程序。 我更喜欢这种方式,因为它只有一步并且没有配置过程。

xvfb-run java -jar selenium-server-standalone-2.45.0.jar

#Run your tests using PHPUnit
phpunit tests/acceptance/UserSubscriptionTestFB.php
Headless test two

Another useful headless browser is HtmlUnit. It can emulate pages and interaction through an API. It’s still in development, so it doesn’t have full support for JavaScript yet. You can read more about it on their website.

另一个有用的无头浏览器是 HtmlUnit 。 它可以通过API模拟页面和交互。 它仍在开发中,因此尚不完全支持JavaScript。 您可以在他们的网站上了解更多信息。

  • https://github.com/facebook/php-webdriver/wiki

    https://github.com/facebook/php-webdriver/wiki

  • http://www.thoughtworks.com/insights/blog/happy-10th-birthday-selenium

    http://www.thoughtworks.com/insights/blog/happy-10th-birthday-selenium

  • http://www.seleniumhq.org/docs/index.jsp

    http://www.seleniumhq.org/docs/index.jsp

结论 (Conclusion)

In this article we introduced the Selenium WebDriver API and showed how we can use it for our acceptance testing process. Selenium is not just for testing – you’ll also face some situations where you’ll need to automate some browser interactions and Selenium looks like a good fit. Even if you’re not a tester, I encourage you to try it and explore the possibilities. Don’t forget to let us know what you think in the comments below!

在本文中,我们介绍了Selenium WebDriver API,并展示了如何在接受测试过程中使用它。 Selenium不仅用于测试-您还将面临一些需要自动进行一些浏览器交互的情况,Selenium看起来很合适。 即使您不是测试人员,我也鼓励您尝试一下并探索各种可能性。 不要忘记在下面的评论中告诉我们您的想法!

翻译自: https://www.sitepoint.com/using-the-selenium-web-driver-api-with-phpunit/

selenium api

culi4814
关注 关注
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
php自动测试工具,使用 php-webdriver 实现自动化测试
weixin_42719781的博客
03-10 882
本文我们讨论一下如何使用 php 实现自动化测试。一、技术选型php + facebook/webdriver + seleniumSelenium是一套完整的Web应用程序测试系统,它提供了一系列的操作浏览器的 APIwebdriver 是 facebook 开发的一套 selenium API 的客户端组件,使用 composer 作为依赖管理工具。二、环境搭建php 的开发环境webdriv...
phpunit-selenium:用于PHPUnitSelenium RC集成
04-13
PHPUnitSelenium 该程序包包含一个Selenium2TestCase类,可用于对Selenium 2运行端到端测试... 这两个受支持的行仅使用Selenium2TestCase类与Selenium 2 API一起使用。 旧版本1.x不再保留,但将继续可用于SeleniumTestC
php-selenium-client, PHPSelenium WebDriver API的交互.zip
10-10
php-selenium-client, PHPSelenium WebDriver API的交互 php-seleniumclientPHPSelenium WebDriver API的交互##Description这个库允许在PHP中与 selenium 服务器V2交互。 它通过官方JsonWireProtocol与API
selenium安装与使用_将SeleniumPHPUnit一起使用
culh2177的博客
08-29 273
selenium安装与使用Testing is a really wide subject, whether it be unit testing, functional testing, acceptance testing, etc. In this article, we’re going to see how you can do acceptance testing using Sele...
php phpunit selenium,在XAMPP环境下安装PHPUnit+Selenium
weixin_36265507的博客
03-28 75
Selenium服务器端安装很方便,本文不再做介绍了。XAMPP集成环境默认已经带了PEAR和PHPUnit了,但是版本较低,准备更新到最新版。1) 更新PEAR通道:pear update-channels2) 更新PEAR自身和其现有的包:pear upgrade -all在cmd下,执行上面两个命令,发现老是报错,看了下错误信息,应该是安装到C盘,没有权限建立文件夹导致。但是我的XAMPP应...
php phpunit selenium,PHPUnitSelenium
weixin_30792221的博客
03-28 125
PHPUnit_Extensions_SeleniumTestCasePHPUnit_Extensions_SeleniumTestCase测试用例扩展将同Selenium RC通话的客户/服务器协议实现为专门用于web测试的断言方法。范例 19.1显示如何测试http://www.example.com/站点的元素的内容。范例 19.1: PHPUnit_Extensions_SeleniumT...
php phpunit selenium,phpunit+selenium环境筹建
weixin_34547317的博客
03-28 132
phpunit+selenium环境搭建这个环境搭建遇到了挺多麻烦,最终还是没能自己解决,幸好有同事“青蛙”的帮忙解决了这个问题!在这里把本人亲测步骤给大家列一下,希望给大家提供方便!安装pear:Go-pear.phar下载地址:http://download.csdn.net/detail/e421083458/4602207下载go-pear.phar文件到C:\wamp\bin\php\p...
phpunit api PHPUnit_Extensions_SeleniumTestCase
chinabluexfw的专栏
06-03 1691
1 要使用 PHPUnit_Extensions_SeleniumTestCase  功能 必须先安装Selenium扩展,安装命令如下  selenium 需要先curl扩展,所有安装/PHPUnit_Selenium 时往往提示错误 phpunit/PHPUnit_Selenium requires PHP extension "curl" 执行以下命令先安装curl,然后重启apach
selenium java pause_Selenium 使用方法小结
weixin_36463040的博客
02-25 267
基本介绍:Selenium工具专门为WEB应用程序编写的一个验收测试工具。Selenium的核心:browser bot,是用JAVASCRIPT编写的。Selenium工具有4种:Selenium IDE, Selenium Control, Selenium Core这儿我们主要总结了Selenium-IDE工具Selenium-IDE只限于firefox浏览器中使用Selenium命令分成...
java web截屏_如何使用Selenium WebDriver截屏
weixin_36221941的博客
02-16 150
有谁知道是否可以使用Selenium WebDriver截屏? (注:不是硒RC)#1楼吉顿import org.openqa.selenium.OutputType as OutputTypeimport org.apache.commons.io.FileUtils as FileUtilsimport java.io.File as Fileimport org.openqa.seleniu...
passbolt_selenium:PassboltSelenium测试
05-05
____ __ ____ / __ \____ _____ ____/ /_ ____ / / /_ / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/ / ____/ /_/ (__ |__ ) /_/ / /_/ / / /_ /_/ \__,_/____/____/_.___/\____/_/\__/ The open source password ...
PHPUnit_Selenium.zip
07-19
Selenium RC integration for PHPUnit 安装方法:sudo pear install phpunit/PHPUnit_Selenium 标签:PHPUnit
phpunit+selenium测试环境搭建浅谈
06-07
这是我个人对phpunit+selenium测试环境搭建的一些总结绝对原创,本人只是菜鸟水平有很多没有写到的地方还望多多包涵。
Laravel开发-phpunit-selenium-webdriver
08-28
Laravel开发-phpunit-selenium-webdriver WebDriver支持使用Fluent测试APIphpunit Selenium测试用例。
windows下安装phpunit_selenium的一些问题
怕什么真理无穷,进一寸有一寸的欢喜
08-01 848
安装phpunit selenium时执行命令pear install phpunit/PHPUnit_Selenium
operator <=> (spaceship operator)
janeqi1987的专栏
05-28 966
= 与!= 操作符为了检查是否相等,现在定义== 操作符就够了。当编译器找不到表达式的匹配声明a!=b 时,编译器会重写表达式并查找!(a==b)。若这不起作用,编译器也会尝试改变操作数的顺序,所以也会尝试!(b==a):a!=b,!(b==a)因此,对于TypeA 的a 和TypeB 的b,编译器将能够识别并编译a!= b若需要的话,可以这样做• 一个独立函数operator!• 一个独立函数operator==(TypeA, TypeB)
Spring6基础笔记
质胜文则野,文胜质则史。文质彬彬,然后君子。
05-21 1226
Spring 是一款主流的 Java EE 轻量级开源框架 ,Spring 由“Spring 之父”Rod Johnson 提出并创立,其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring 框架除了自己提供功能外,还提供整合其他技术和框架的能力。Spring 自诞生以来备受青睐,一直被广大开发人员作为 Java 企业级应用程序开发的首选。时至今日,Spring 俨然
Java 异常处理中try-catch块、finally子句以及自定义异常的使用
最新发布
Itmastergo的博客
05-31 761
异常是程序运行过程中出现的非正常情况。Java 使用异常类(Exception 类及其子类)来表示这些异常情况。异常处理的核心思想是将正常的程序流程与异常处理流程分离开来,使代码更加清晰和可维护。Throwable 类:所有异常和错误的基类。Error 类:表示系统级的错误,程序通常无法处理,比如内存不足(OutOfMemoryError)。Exception 类:表示程序中可以处理的异常情况。RuntimeException 类。
selenium send_keys怎么使用
03-20
Selenium 的 send_keys() 方法可以用来模拟用户在输入框中输入文本。使用该方法时,需要先定位到输入框,然后调用 send_keys() 方法并传入要输入的文本即可。例如: ```python from selenium import webdriver ...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 全世界禁用谷歌的五大国家_5个国家站在Google与世界统治之间 52123
  • SitePoint播客#69:让我们移居芬兰 22837
  • java成熟后台开源_开源成熟 19052
  • wordpress 漏洞_轻松发现WordPress漏洞 13260
  • html绘制矩形_如何在HTML中绘制矩形 11406

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • svg嵌套svg_SVG 101:什么是SVG?
  • gulp4.0.2_如何迁移到Gulp.js 4.0
  • 使用WordPress设置API构建自定义管理页面
2020年1241篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司南山网站推广工具多少钱怒江企业网站制作报价茂名企业网站设计报价南平seo优化哪家好茂名建网站多少钱长春优秀网站设计报价海东seo报价防城港品牌网站设计哪家好思茅网站优化按天计费价格拉萨网站建设哪家好兰州SEO按天收费公司汉中百姓网标王推广多少钱罗湖网站推广工具公司汉中网站优化按天计费多少钱宜宾企业网站制作推荐淮安网站优化按天计费多少钱珠海企业网站改版公司莆田网站改版多少钱承德网站优化价格茂名网页制作哪家好毕节模板推广报价延安品牌网站设计报价亳州网站设计推荐淮安设计公司网站张家口seo网站优化池州网站关键词优化公司泰安网站优化排名哪家好呼和浩特百姓网标王推广光明品牌网站设计价格咸阳网站优化按天扣费哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化