使用 phpunit/selenium 保持 selenium 浏览器打开

发布于 2024-11-06 00:24:37 字数 148 浏览 3 评论 0原文

当测试失败时,运行 selenium 测试的浏览器将关闭。这在尝试调试时没有帮助。我知道我可以在失败时选择屏幕截图,但如果没有整个上下文,这并没有帮助。在浏览器仍然可用的情况下,我可以回击并检查发生了什么。

即使断言失败或找不到元素,有没有办法让浏览器保持打开状态?

when the tests fail, the browser that the selenium tests were running on closes. this is unhelpful when trying to debug. i know i have the option of a screen shot upon failure, but that doesn't help without the entire context. with the browser still available, i can hit back and inspect what was going on.

is there a way to keep the browser open even when asserts fail or elements aren't found?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

关于从前 2024-11-13 00:24:37

几周后我随机想到了这一点。

启动服务器时,最后使用选项 -browserSessionReuse。这将使一个浏览器会话在整个测试过程中保持打开状态,并且不会在失败时关闭

figured it out randomly many weeks later.

when starting the server, use the option -browserSessionReuse at the end. this will keep one browser session open throughout the tests and not close on failure

爱的那么颓废 2024-11-13 00:24:37

您可能会在测试结束时调用 selenium.stop() 。您需要注释掉该行代码,并确保您的 selenium 对象在测试结束时不会被破坏。这将使窗口保持打开状态。 此处已回答相同问题

You might be calling selenium.stop() at the end of the test. You need to comment out that line of code and make sure that your selenium object is not destroyed at the end of the test. This will keep the window open. Same question has been answered here

如何视而不见 2024-11-13 00:24:37

关于 https://stackoverflow.com/a/6904808/654026 上关于 -browserSessionReuse 的答案,请记住,您必须在测试执行之间清理 cookie。否则你可能很难调试错误。

Regarding the answer about -browserSessionReuse at https://stackoverflow.com/a/6904808/654026, keep in mind that you will have to deal with cleaning the cookies between tests executions. Otherwise you may have difficult to debug errors.

将军与妓 2024-11-13 00:24:37

一个简单的解决方案是在测试 setUp() 方法中将会话 $stopped 属性设置为 true。由于该属性是私有的,因此我们需要使用 Reflection api。

    function setUp() {

        ....

        // Set the private property $stopped of session to true, so the window is not closed on error or at the end of tests
        $myClassReflection = new \ReflectionClass( get_class( $this->prepareSession() ) );
        $secret            = $myClassReflection->getProperty( 'stopped' );
        $secret->setAccessible( true );
        $secret->setValue( $this->prepareSession(), true );

        ...
}

A simple solution is to set the session $stopped property to true, in the test setUp() method. As the property is private, we need to use the Reflection api.

    function setUp() {

        ....

        // Set the private property $stopped of session to true, so the window is not closed on error or at the end of tests
        $myClassReflection = new \ReflectionClass( get_class( $this->prepareSession() ) );
        $secret            = $myClassReflection->getProperty( 'stopped' );
        $secret->setAccessible( true );
        $secret->setValue( $this->prepareSession(), true );

        ...
}
甜扑 2024-11-13 00:24:37

经过长时间尝试创建一个相对干净的解决方法后,我现在采取了一种非常肮脏但非常简单的技巧。 phpunit\selenium 源代码不容易重写,如果有用于创建 Session 对象的工厂就好了。我尝试通过覆盖和代理对象来侵入对象创建,但仍然无法使其工作。最后,我不想在这上面花更多的时间,而是走上了最简单和最肮脏的道路,即直接破解 PHPUnit_Extensions_Selenium2TestCase_Session 和 PHPUnit_Extensions_Selenium2TestCase 类的代码。
在 PHPUnit_Extensions_Selenium2TestCase 中插入了一个静态 $_instance,可用于检查是否存在测试失败情况。在PHPUnit_Extensions_Selenium2TestCase_Session中拦截了stop()方法并查询TestCase的状态。工作起来就像一个魅力,但肮脏肮脏肮脏。

PHPUnit_Extensions_Selenium2TestCase:

private static $_instance;
public static function getInstance() { return self::$_instance; }
....
public function __construct($name = NULL, array $data = array(), $dataName = '')
{
    self::$_instance = $this;
    ....
}

PHPUnit_Extensions_Selenium2TestCase_Session:

public function stop()
{
    if ($this->stopped || $this->hasFailedTests()) {
        return;
    }
    ....
}

private function hasFailedTests()
{
    $status = PHPUnit_Extensions_Selenium2TestCase::getInstance()->getStatus();
    return $status == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
    || $status == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
}

After long hours of trying to create a relatively clean workaround, I now resorted to a very dirty, but very easy hack. The phpunit\selenium source code is not easy to override, it would have been nice if there had been factories used to create the Session objects. I tried to hack into the object creation by overriding and proxying objects, but still couldn't get it to work. Finally, I didn't want to spend more hours on this and went down the easiest and dirtiest path, i.e. hacked the code of the PHPUnit_Extensions_Selenium2TestCase_Session and PHPUnit_Extensions_Selenium2TestCase classes directly.
In PHPUnit_Extensions_Selenium2TestCase inserted a static $_instance that can be used to check if there was a test failure condition. In PHPUnit_Extensions_Selenium2TestCase_Session intercepted the stop() method and queried the status of the TestCase. Works like a charm, but dirty dirty dirty.

PHPUnit_Extensions_Selenium2TestCase:

private static $_instance;
public static function getInstance() { return self::$_instance; }
....
public function __construct($name = NULL, array $data = array(), $dataName = '')
{
    self::$_instance = $this;
    ....
}

PHPUnit_Extensions_Selenium2TestCase_Session:

public function stop()
{
    if ($this->stopped || $this->hasFailedTests()) {
        return;
    }
    ....
}

private function hasFailedTests()
{
    $status = PHPUnit_Extensions_Selenium2TestCase::getInstance()->getStatus();
    return $status == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
    || $status == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
}
海未深 2024-11-13 00:24:37

这是一个更干净的解决方案。覆盖与会话创建相关的所有类。 Session 类是会话关闭的地方,因此需要重写 stop() 方法。

TODO:添加参数来控制行为,是否以及何时保持浏览器窗口打开。

覆盖5个类:PHPUnit_Extensions_Selenium2TestCase、PHPUnit_Extensions_Selenium2TestCase_Driver、PHPUnit_Extensions_Selenium2TestCase_Session、PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated、PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared。
创建了 2 个引导文件,1 个用于共享浏览器会话,1 个用于独立浏览器会话。
显示 1 个示例测试。

OkxSelenium2TestCase:

namespace OKInfoTech\PhpUnit\Selenium;

abstract class OkxSelenium2TestCase extends \PHPUnit_Extensions_Selenium2TestCase
{
    private static $_instance;
    public static function getInstance() { return self::$_instance; }

    public function __construct($name = NULL, array $data = array(), $dataName = '')
    {
        self::$_instance = $this;
        parent::__construct($name, $data, $dataName);

        $params = array(
            'host' => 'localhost',
            'port' => 4444,
            'browser' => NULL,
            'browserName' => NULL,
            'desiredCapabilities' => array(),
            'seleniumServerRequestsTimeout' => 60
        );
        $this->setUpSessionStrategy($params);
    }

    protected function setUpSessionStrategy($params)
    {
        parent::setUpSessionStrategy($params);
        if (isset($params['sessionStrategy'])) {
            $strat = $params['sessionStrategy'];
            switch ($strat) {
                case "isolated":
                    self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Isolated;
                    break;
                case "shared":
                    self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Shared(new OkxSelenium2TestCase_SessionStrategy_Isolated);
                    break;
            }
        } else {
            self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Isolated;
        }
        $this->localSessionStrategy = self::$browserSessionStrategy;
    }
}

OkxSelenium2TestCase_Driver:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_Driver extends \PHPUnit_Extensions_Selenium2TestCase_Driver
{
    private $seleniumServerUrl;
    private $seleniumServerRequestsTimeout;

    public function __construct(\PHPUnit_Extensions_Selenium2TestCase_URL $seleniumServerUrl, $timeout = 60)
    {
        $this->seleniumServerUrl = $seleniumServerUrl;
        $this->seleniumServerRequestsTimeout = $timeout;
        parent::__construct($seleniumServerUrl, $timeout);
    }

    public function startSession(array $desiredCapabilities, \PHPUnit_Extensions_Selenium2TestCase_URL $browserUrl)
    {
        $sessionCreation = $this->seleniumServerUrl->descend("/wd/hub/session");
        $response = $this->curl('POST', $sessionCreation, array(
            'desiredCapabilities' => $desiredCapabilities
        ));
        $sessionPrefix = $response->getURL();

        $timeouts = new \PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts(
            $this,
            $sessionPrefix->descend('timeouts'),
            $this->seleniumServerRequestsTimeout * 1000
        );
        return new OkxSelenium2TestCase_Session(
            $this,
            $sessionPrefix,
            $browserUrl,
            $timeouts
        );
    }
}

OkxSelenium2TestCase_Session:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_Session extends \PHPUnit_Extensions_Selenium2TestCase_Session
{
    public function stop()
    {
        if ($this->hasFailedTests()) {
            return;
        }
        parent::stop();
    }

    private function hasFailedTests()
    {
        $status = OkxSelenium2TestCase::getInstance()->getStatus();
        return $status == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
        || $status == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
    }
}

OkxSelenium2TestCase_SessionStrategy_Isolated:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_SessionStrategy_Isolated extends \PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated
{
    public function session(array $parameters)
    {
        $seleniumServerUrl = \PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($parameters['host'], $parameters['port']);
        $driver = new OkxSelenium2TestCase_Driver($seleniumServerUrl, $parameters['seleniumServerRequestsTimeout']);
        $capabilities = array_merge($parameters['desiredCapabilities'],
            array(
                'browserName' => $parameters['browserName']
            ));
        $session = $driver->startSession($capabilities, $parameters['browserUrl']);
        return $session;
    }
}

OkxSelenium2TestCase_SessionStrategy_Shared:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_SessionStrategy_Shared extends \PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared
{

}

bootstrapIsolated.php:

require_once dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';

spl_autoload_register(
    function ($class) {
        static $classes = NULL;
        static $path = NULL;

        if ($classes === NULL) {
            $classes = [
                'okinfotech\phpunit\selenium\okxselenium2testcase' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_driver' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Driver.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_session' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Session.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_isolated' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Isolated.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_shared' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Shared.php',
            ];
            $path = dirname(dirname(dirname(dirname(__FILE__)))) . '/vendor/';
        }

        $cn = strtolower($class);

        if (isset($classes[$cn])) {
            require $path . $classes[$cn];
        }
    }
);

use OKInfoTech\PhpUnit\Selenium\OkxSelenium2TestCase;
OkxSelenium2TestCase::shareSession(false);

bootstrapShared.php:

require_once dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';

spl_autoload_register(
    function ($class) {
        static $classes = NULL;
        static $path = NULL;

        if ($classes === NULL) {
            $classes = [
                'okinfotech\phpunit\selenium\okxselenium2testcase' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_driver' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Driver.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_session' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Session.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_isolated' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Isolated.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_shared' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Shared.php',
            ];
            $path = dirname(dirname(dirname(dirname(__FILE__)))) . '/vendor/';
        }

        $cn = strtolower($class);

        if (isset($classes[$cn])) {
            require $path . $classes[$cn];
        }
    }
);

use OKInfoTech\PhpUnit\Selenium\OkxSelenium2TestCase;
OkxSelenium2TestCase::shareSession(true);

Selenium02Test:

class Selenium02Test extends OkxSelenium2TestCase
{
    public static function setUpBeforeClass()
    {
    }

    public static function tearDownAfterClass()
    {
    }

    public function setUp()
    {
        $this->setHost('...');
        $this->setPort(4444);
        $this->setBrowser('chrome');
        //$this->setBrowser('firefox');
        $this->setBrowserUrl('...');
    }

    public function tearDown()
    {
    }

    public function testPageExists()
    {
        $this->url('/');
        // test if browser window stays open when test fails
        $this->assertTrue(false);
    }
}

Here a cleaner solution. Overridden all classes involved with session creation. Session class is where the session is closed, so the stop() method needed to be overridden.

TODO: add parameters to control behaviour, if and when to keep browser window open or not.

Overridden 5 classes: PHPUnit_Extensions_Selenium2TestCase, PHPUnit_Extensions_Selenium2TestCase_Driver, PHPUnit_Extensions_Selenium2TestCase_Session, PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated, PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared.
Created 2 bootstrap files, 1 for shared browser sessions, 1 for isolated browser sessions.
Showing 1 example test.

OkxSelenium2TestCase:

namespace OKInfoTech\PhpUnit\Selenium;

abstract class OkxSelenium2TestCase extends \PHPUnit_Extensions_Selenium2TestCase
{
    private static $_instance;
    public static function getInstance() { return self::$_instance; }

    public function __construct($name = NULL, array $data = array(), $dataName = '')
    {
        self::$_instance = $this;
        parent::__construct($name, $data, $dataName);

        $params = array(
            'host' => 'localhost',
            'port' => 4444,
            'browser' => NULL,
            'browserName' => NULL,
            'desiredCapabilities' => array(),
            'seleniumServerRequestsTimeout' => 60
        );
        $this->setUpSessionStrategy($params);
    }

    protected function setUpSessionStrategy($params)
    {
        parent::setUpSessionStrategy($params);
        if (isset($params['sessionStrategy'])) {
            $strat = $params['sessionStrategy'];
            switch ($strat) {
                case "isolated":
                    self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Isolated;
                    break;
                case "shared":
                    self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Shared(new OkxSelenium2TestCase_SessionStrategy_Isolated);
                    break;
            }
        } else {
            self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Isolated;
        }
        $this->localSessionStrategy = self::$browserSessionStrategy;
    }
}

OkxSelenium2TestCase_Driver:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_Driver extends \PHPUnit_Extensions_Selenium2TestCase_Driver
{
    private $seleniumServerUrl;
    private $seleniumServerRequestsTimeout;

    public function __construct(\PHPUnit_Extensions_Selenium2TestCase_URL $seleniumServerUrl, $timeout = 60)
    {
        $this->seleniumServerUrl = $seleniumServerUrl;
        $this->seleniumServerRequestsTimeout = $timeout;
        parent::__construct($seleniumServerUrl, $timeout);
    }

    public function startSession(array $desiredCapabilities, \PHPUnit_Extensions_Selenium2TestCase_URL $browserUrl)
    {
        $sessionCreation = $this->seleniumServerUrl->descend("/wd/hub/session");
        $response = $this->curl('POST', $sessionCreation, array(
            'desiredCapabilities' => $desiredCapabilities
        ));
        $sessionPrefix = $response->getURL();

        $timeouts = new \PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts(
            $this,
            $sessionPrefix->descend('timeouts'),
            $this->seleniumServerRequestsTimeout * 1000
        );
        return new OkxSelenium2TestCase_Session(
            $this,
            $sessionPrefix,
            $browserUrl,
            $timeouts
        );
    }
}

OkxSelenium2TestCase_Session:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_Session extends \PHPUnit_Extensions_Selenium2TestCase_Session
{
    public function stop()
    {
        if ($this->hasFailedTests()) {
            return;
        }
        parent::stop();
    }

    private function hasFailedTests()
    {
        $status = OkxSelenium2TestCase::getInstance()->getStatus();
        return $status == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
        || $status == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
    }
}

OkxSelenium2TestCase_SessionStrategy_Isolated:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_SessionStrategy_Isolated extends \PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated
{
    public function session(array $parameters)
    {
        $seleniumServerUrl = \PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($parameters['host'], $parameters['port']);
        $driver = new OkxSelenium2TestCase_Driver($seleniumServerUrl, $parameters['seleniumServerRequestsTimeout']);
        $capabilities = array_merge($parameters['desiredCapabilities'],
            array(
                'browserName' => $parameters['browserName']
            ));
        $session = $driver->startSession($capabilities, $parameters['browserUrl']);
        return $session;
    }
}

OkxSelenium2TestCase_SessionStrategy_Shared:

namespace OKInfoTech\PhpUnit\Selenium;

class OkxSelenium2TestCase_SessionStrategy_Shared extends \PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared
{

}

bootstrapIsolated.php:

require_once dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';

spl_autoload_register(
    function ($class) {
        static $classes = NULL;
        static $path = NULL;

        if ($classes === NULL) {
            $classes = [
                'okinfotech\phpunit\selenium\okxselenium2testcase' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_driver' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Driver.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_session' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Session.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_isolated' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Isolated.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_shared' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Shared.php',
            ];
            $path = dirname(dirname(dirname(dirname(__FILE__)))) . '/vendor/';
        }

        $cn = strtolower($class);

        if (isset($classes[$cn])) {
            require $path . $classes[$cn];
        }
    }
);

use OKInfoTech\PhpUnit\Selenium\OkxSelenium2TestCase;
OkxSelenium2TestCase::shareSession(false);

bootstrapShared.php:

require_once dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';

spl_autoload_register(
    function ($class) {
        static $classes = NULL;
        static $path = NULL;

        if ($classes === NULL) {
            $classes = [
                'okinfotech\phpunit\selenium\okxselenium2testcase' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_driver' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Driver.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_session' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Session.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_isolated' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Isolated.php',
                'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_shared' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Shared.php',
            ];
            $path = dirname(dirname(dirname(dirname(__FILE__)))) . '/vendor/';
        }

        $cn = strtolower($class);

        if (isset($classes[$cn])) {
            require $path . $classes[$cn];
        }
    }
);

use OKInfoTech\PhpUnit\Selenium\OkxSelenium2TestCase;
OkxSelenium2TestCase::shareSession(true);

Selenium02Test:

class Selenium02Test extends OkxSelenium2TestCase
{
    public static function setUpBeforeClass()
    {
    }

    public static function tearDownAfterClass()
    {
    }

    public function setUp()
    {
        $this->setHost('...');
        $this->setPort(4444);
        $this->setBrowser('chrome');
        //$this->setBrowser('firefox');
        $this->setBrowserUrl('...');
    }

    public function tearDown()
    {
    }

    public function testPageExists()
    {
        $this->url('/');
        // test if browser window stays open when test fails
        $this->assertTrue(false);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文