+ Add php-webdriver tools.
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInita9d739e5f031abd9c929e6b2f18db2f1::getLoader();
|
||||
@@ -0,0 +1,572 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
* @private
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Composer\Semver\VersionParser;
|
||||
|
||||
/**
|
||||
* This class is copied in every Composer installed project and available to all
|
||||
*
|
||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||
*
|
||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class InstalledVersions
|
||||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private static $canGetVendors;
|
||||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
/**
|
||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackages()
|
||||
{
|
||||
$packages = array();
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
$packages[] = array_keys($installed['versions']);
|
||||
}
|
||||
|
||||
if (1 === \count($packages)) {
|
||||
return $packages[0];
|
||||
}
|
||||
|
||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all package names with a specific type e.g. 'library'
|
||||
*
|
||||
* @param string $type
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
*/
|
||||
public static function getInstalledPackagesByType($type)
|
||||
{
|
||||
$packagesByType = array();
|
||||
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
foreach ($installed['versions'] as $name => $package) {
|
||||
if (isset($package['type']) && $package['type'] === $type) {
|
||||
$packagesByType[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $packagesByType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package is installed
|
||||
*
|
||||
* This also returns true if the package name is provided or replaced by another package
|
||||
*
|
||||
* @param string $packageName
|
||||
* @param bool $includeDevRequirements
|
||||
* @return bool
|
||||
*/
|
||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (isset($installed['versions'][$packageName])) {
|
||||
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given package satisfies a version constraint
|
||||
*
|
||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||
*
|
||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||
*
|
||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||
* @param string $packageName
|
||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||
* @return bool
|
||||
*/
|
||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||
{
|
||||
$constraint = $parser->parseConstraints($constraint);
|
||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||
|
||||
return $provided->matches($constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||
*
|
||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||
* whether a given version of a package is installed, and not just whether it exists
|
||||
*
|
||||
* @param string $packageName
|
||||
* @return string Version constraint usable with composer/semver
|
||||
*/
|
||||
public static function getVersionRanges($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ranges = array();
|
||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||
}
|
||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||
}
|
||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||
}
|
||||
|
||||
return implode(' || ', $ranges);
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||
*/
|
||||
public static function getPrettyVersion($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['pretty_version'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||
*/
|
||||
public static function getReference($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $installed['versions'][$packageName]['reference'];
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $packageName
|
||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||
*/
|
||||
public static function getInstallPath($packageName)
|
||||
{
|
||||
foreach (self::getInstalled() as $installed) {
|
||||
if (!isset($installed['versions'][$packageName])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||
}
|
||||
|
||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
$installed = self::getInstalled();
|
||||
|
||||
return $installed[0]['root'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw installed.php data for custom implementations
|
||||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = include __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
|
||||
return self::$installed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
return self::getInstalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lets you reload the static array from another file
|
||||
*
|
||||
* This is only useful for complex integrations in which a project needs to use
|
||||
* this class but then also needs to execute another project's autoloader in process,
|
||||
* and wants to ensure both projects have access to their version of installed.php.
|
||||
*
|
||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||
* the data it needs from this class, then call reload() with
|
||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||
* the project in which it runs can then also use this class safely, without
|
||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||
*
|
||||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
self::$installed = $data;
|
||||
self::$installedByVendor = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
if (null === self::$canGetVendors) {
|
||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||
}
|
||||
|
||||
$installed = array();
|
||||
|
||||
if (self::$canGetVendors) {
|
||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir];
|
||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
|
||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||
self::$installed = $installed[count($installed) - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$installed) {
|
||||
// only require the installed.php file if this file is loaded from its dumped location,
|
||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||
self::$installed = require __DIR__ . '/installed.php';
|
||||
} else {
|
||||
self::$installed = array();
|
||||
}
|
||||
}
|
||||
$installed[] = self::$installed;
|
||||
|
||||
return $installed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
);
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'2a3c2110e8e0295330dc3d11a4cbc4cb' => $vendorDir . '/php-webdriver/webdriver/lib/Exception/TimeoutException.php',
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
||||
'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
|
||||
'Facebook\\WebDriver\\' => array($vendorDir . '/php-webdriver/webdriver/lib'),
|
||||
);
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInita9d739e5f031abd9c929e6b2f18db2f1
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInita9d739e5f031abd9c929e6b2f18db2f1', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInita9d739e5f031abd9c929e6b2f18db2f1', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInita9d739e5f031abd9c929e6b2f18db2f1::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
$includeFiles = \Composer\Autoload\ComposerStaticInita9d739e5f031abd9c929e6b2f18db2f1::$files;
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequirea9d739e5f031abd9c929e6b2f18db2f1($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileIdentifier
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
function composerRequirea9d739e5f031abd9c929e6b2f18db2f1($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInita9d739e5f031abd9c929e6b2f18db2f1
|
||||
{
|
||||
public static $files = array (
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'2a3c2110e8e0295330dc3d11a4cbc4cb' => __DIR__ . '/..' . '/php-webdriver/webdriver/lib/Exception/TimeoutException.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'S' =>
|
||||
array (
|
||||
'Symfony\\Polyfill\\Php80\\' => 23,
|
||||
'Symfony\\Polyfill\\Mbstring\\' => 26,
|
||||
'Symfony\\Component\\Process\\' => 26,
|
||||
),
|
||||
'F' =>
|
||||
array (
|
||||
'Facebook\\WebDriver\\' => 19,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Symfony\\Polyfill\\Php80\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
|
||||
),
|
||||
'Symfony\\Polyfill\\Mbstring\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
|
||||
),
|
||||
'Symfony\\Component\\Process\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/process',
|
||||
),
|
||||
'Facebook\\WebDriver\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/php-webdriver/webdriver/lib',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
|
||||
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
|
||||
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
|
||||
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInita9d739e5f031abd9c929e6b2f18db2f1::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInita9d739e5f031abd9c929e6b2f18db2f1::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInita9d739e5f031abd9c929e6b2f18db2f1::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"name": "php-webdriver/webdriver",
|
||||
"version": "1.12.1",
|
||||
"version_normalized": "1.12.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-webdriver/php-webdriver.git",
|
||||
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
|
||||
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"php": "^5.6 || ~7.0 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.12",
|
||||
"symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"replace": {
|
||||
"facebook/webdriver": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
|
||||
"php-coveralls/php-coveralls": "^2.4",
|
||||
"php-mock/php-mock-phpunit": "^1.1 || ^2.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-SimpleXML": "For Firefox profile creation"
|
||||
},
|
||||
"time": "2022-05-03T12:16:34+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"lib/Exception/TimeoutException.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Facebook\\WebDriver\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
|
||||
"homepage": "https://github.com/php-webdriver/php-webdriver",
|
||||
"keywords": [
|
||||
"Chromedriver",
|
||||
"geckodriver",
|
||||
"php",
|
||||
"selenium",
|
||||
"webdriver"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-webdriver/php-webdriver/issues",
|
||||
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.1"
|
||||
},
|
||||
"install-path": "../php-webdriver/webdriver"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.26.0",
|
||||
"version_normalized": "1.26.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
|
||||
"reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"time": "2022-05-24T11:49:31+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.26-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/polyfill-mbstring"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.26.0",
|
||||
"version_normalized": "1.26.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
|
||||
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"time": "2022-05-10T07:21:04+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.26-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/polyfill-php80"
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v5.4.8",
|
||||
"version_normalized": "5.4.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
|
||||
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-php80": "^1.16"
|
||||
},
|
||||
"time": "2022-04-08T05:07:18+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Process\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v5.4.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/process"
|
||||
}
|
||||
],
|
||||
"dev": true,
|
||||
"dev-package-names": []
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => '__root__',
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => NULL,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'__root__' => array(
|
||||
'pretty_version' => '1.0.0+no-version-set',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => NULL,
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'facebook/webdriver' => array(
|
||||
'dev_requirement' => false,
|
||||
'replaced' => array(
|
||||
0 => '*',
|
||||
),
|
||||
),
|
||||
'php-webdriver/webdriver' => array(
|
||||
'pretty_version' => '1.12.1',
|
||||
'version' => '1.12.1.0',
|
||||
'reference' => 'b27ddf458d273c7d4602106fcaf978aa0b7fe15a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../php-webdriver/webdriver',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.26.0',
|
||||
'version' => '1.26.0.0',
|
||||
'reference' => '9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.26.0',
|
||||
'version' => '1.26.0.0',
|
||||
'reference' => 'cfa0ae98841b9e461207c13ab093d76b0fa7bace',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/process' => array(
|
||||
'pretty_version' => 'v5.4.8',
|
||||
'version' => '5.4.8.0',
|
||||
'reference' => '597f3fff8e3e91836bb0bd38f5718b56ddbde2f3',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/process',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
// platform_check.php @generated by Composer
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 70205)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||
} elseif (!headers_sent()) {
|
||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
->in([__DIR__ . '/lib', __DIR__ . '/tests']);
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'binary_operator_spaces' => true,
|
||||
'blank_line_before_statement' => ['statements' => ['return', 'try']],
|
||||
'braces' => ['allow_single_line_anonymous_class_with_empty_body' => true, 'allow_single_line_closure' => true],
|
||||
'cast_spaces' => true,
|
||||
'class_attributes_separation' => ['elements' => ['method' => 'one']],
|
||||
'clean_namespace' => true,
|
||||
'compact_nullable_typehint' => true,
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
'declare_equal_normalize' => true,
|
||||
'fopen_flag_order' => true,
|
||||
'fopen_flags' => true,
|
||||
'full_opening_tag' => true,
|
||||
'function_typehint_space' => true,
|
||||
'implode_call' => true,
|
||||
'is_null' => true,
|
||||
'lambda_not_used_import' => true,
|
||||
'linebreak_after_opening_tag' => true,
|
||||
'lowercase_cast' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'magic_constant_casing' => true,
|
||||
'magic_method_casing' => true,
|
||||
'mb_str_functions' => true,
|
||||
'native_function_casing' => true,
|
||||
'native_function_type_declaration_casing' => true,
|
||||
'new_with_braces' => true,
|
||||
'no_alias_functions' => true,
|
||||
'no_blank_lines_after_class_opening' => true,
|
||||
'no_blank_lines_after_phpdoc' => true,
|
||||
'no_empty_comment' => true,
|
||||
'no_empty_phpdoc' => true,
|
||||
'no_empty_statement' => true,
|
||||
'normalize_index_brace' => true,
|
||||
'no_extra_blank_lines' => [
|
||||
'tokens' => [
|
||||
'break',
|
||||
'case',
|
||||
'continue',
|
||||
'curly_brace_block',
|
||||
'default',
|
||||
'extra',
|
||||
'parenthesis_brace_block',
|
||||
'return',
|
||||
'square_brace_block',
|
||||
'switch',
|
||||
'throw',
|
||||
'use',
|
||||
'use_trait',
|
||||
],
|
||||
],
|
||||
'no_leading_import_slash' => true,
|
||||
'no_leading_namespace_whitespace' => true,
|
||||
'no_singleline_whitespace_before_semicolons' => true,
|
||||
'no_trailing_comma_in_singleline_array' => true,
|
||||
'no_unreachable_default_argument_value' => true,
|
||||
'no_unused_imports' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_useless_return' => true,
|
||||
'no_useless_sprintf' => true,
|
||||
'no_whitespace_in_blank_line' => true,
|
||||
'object_operator_without_whitespace' => true,
|
||||
'ordered_class_elements' => true,
|
||||
'ordered_imports' => true,
|
||||
'php_unit_construct' => true,
|
||||
'php_unit_dedicate_assert' => false,
|
||||
'php_unit_expectation' => ['target' => '5.6'],
|
||||
'php_unit_method_casing' => ['case' => 'camel_case'],
|
||||
'php_unit_mock_short_will_return' => true,
|
||||
'php_unit_mock' => true,
|
||||
'php_unit_namespaced' => ['target' => '5.7'],
|
||||
'php_unit_no_expectation_annotation' => true,
|
||||
'php_unit_set_up_tear_down_visibility' => true,
|
||||
'php_unit_test_case_static_method_calls' => ['call_type' => 'this'],
|
||||
'phpdoc_add_missing_param_annotation' => true,
|
||||
'phpdoc_indent' => true,
|
||||
'phpdoc_no_access' => true,
|
||||
// 'phpdoc_no_empty_return' => true, // disabled to allow forward compatibility with PHP 8.1
|
||||
'phpdoc_no_package' => true,
|
||||
'phpdoc_order_by_value' => ['annotations' => ['covers', 'group', 'throws']],
|
||||
'phpdoc_order' => true,
|
||||
'phpdoc_return_self_reference' => true,
|
||||
'phpdoc_scalar' => true,
|
||||
'phpdoc_single_line_var_spacing' => true,
|
||||
'phpdoc_trim' => true,
|
||||
'phpdoc_types' => true,
|
||||
'phpdoc_var_annotation_correct_order' => true,
|
||||
'psr_autoloading' => true,
|
||||
'self_accessor' => true,
|
||||
'set_type_to_cast' => true,
|
||||
'short_scalar_cast' => true,
|
||||
'single_blank_line_before_namespace' => true,
|
||||
'single_quote' => true,
|
||||
'single_space_after_construct' => true,
|
||||
'single_trait_insert_per_statement' => true,
|
||||
'space_after_semicolon' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'strict_param' => true,
|
||||
'switch_continue_to_break' => true,
|
||||
'ternary_operator_spaces' => true,
|
||||
'ternary_to_elvis_operator' => true,
|
||||
'trailing_comma_in_multiline' => ['elements' => ['arrays']],
|
||||
'trim_array_spaces' => true,
|
||||
'unary_operator_spaces' => true,
|
||||
'visibility_required' => ['elements' => ['method', 'property']],
|
||||
'whitespace_after_comma_in_array' => true,
|
||||
'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false],
|
||||
])
|
||||
->setRiskyAllowed(true)
|
||||
->setFinder($finder);
|
||||
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"name": "php-webdriver/webdriver",
|
||||
"description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"webdriver",
|
||||
"selenium",
|
||||
"php",
|
||||
"geckodriver",
|
||||
"chromedriver"
|
||||
],
|
||||
"homepage": "https://github.com/php-webdriver/php-webdriver",
|
||||
"require": {
|
||||
"php": "^5.6 || ~7.0 || ^8.0",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"symfony/polyfill-mbstring": "^1.12",
|
||||
"symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
|
||||
"php-coveralls/php-coveralls": "^2.4",
|
||||
"php-mock/php-mock-phpunit": "^1.1 || ^2.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
"phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
|
||||
},
|
||||
"replace": {
|
||||
"facebook/webdriver": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-SimpleXML": "For Firefox profile creation"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Facebook\\WebDriver\\": "lib/"
|
||||
},
|
||||
"files": [
|
||||
"lib/Exception/TimeoutException.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Facebook\\WebDriver\\": [
|
||||
"tests/unit",
|
||||
"tests/functional"
|
||||
]
|
||||
},
|
||||
"classmap": [
|
||||
"tests/functional/"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"ergebnis/composer-normalize": true
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": [
|
||||
"php -r 'if (PHP_VERSION_ID > 70103) { exit(1); }' || composer install --working-dir=tools/php-cs-fixer --no-progress --no-interaction"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"php -r 'if (PHP_VERSION_ID > 70103) { exit(1); }' || composer update --working-dir=tools/php-cs-fixer --no-progress --no-interaction"
|
||||
],
|
||||
"all": [
|
||||
"@lint",
|
||||
"@analyze",
|
||||
"@test"
|
||||
],
|
||||
"analyze": [
|
||||
"vendor/bin/phpstan analyze -c phpstan.neon --ansi",
|
||||
"tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --diff --dry-run -vvv --ansi",
|
||||
"vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/"
|
||||
],
|
||||
"fix": [
|
||||
"@composer normalize",
|
||||
"tools/php-cs-fixer/vendor/bin/php-cs-fixer fix --diff -vvv || exit 0",
|
||||
"vendor/bin/phpcbf --standard=PSR2 ./lib/ ./tests/"
|
||||
],
|
||||
"lint": [
|
||||
"vendor/bin/parallel-lint -j 10 ./lib ./tests example.php",
|
||||
"@composer validate",
|
||||
"@composer normalize --dry-run"
|
||||
],
|
||||
"preinstall": [
|
||||
"@composer update --no-progress --no-interaction",
|
||||
"@composer require --dev phpstan/phpstan",
|
||||
"@composer require --dev ergebnis/composer-normalize"
|
||||
],
|
||||
"test": [
|
||||
"vendor/bin/phpunit --colors=always"
|
||||
]
|
||||
}
|
||||
}
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver;
|
||||
|
||||
use Facebook\WebDriver\Exception\NoSuchElementException;
|
||||
use Facebook\WebDriver\Exception\UnexpectedTagNameException;
|
||||
use Facebook\WebDriver\Exception\WebDriverException;
|
||||
use Facebook\WebDriver\Support\XPathEscaper;
|
||||
|
||||
/**
|
||||
* Provides helper methods for checkboxes and radio buttons.
|
||||
*/
|
||||
abstract class AbstractWebDriverCheckboxOrRadio implements WebDriverSelectInterface
|
||||
{
|
||||
/** @var WebDriverElement */
|
||||
protected $element;
|
||||
|
||||
/** @var string */
|
||||
protected $type;
|
||||
|
||||
/** @var string */
|
||||
protected $name;
|
||||
|
||||
public function __construct(WebDriverElement $element)
|
||||
{
|
||||
$tagName = $element->getTagName();
|
||||
if ($tagName !== 'input') {
|
||||
throw new UnexpectedTagNameException('input', $tagName);
|
||||
}
|
||||
|
||||
$this->name = $element->getAttribute('name');
|
||||
if ($this->name === null) {
|
||||
throw new WebDriverException('The input does not have a "name" attribute.');
|
||||
}
|
||||
|
||||
$this->element = $element;
|
||||
}
|
||||
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->getRelatedElements();
|
||||
}
|
||||
|
||||
public function getAllSelectedOptions()
|
||||
{
|
||||
$selectedElement = [];
|
||||
foreach ($this->getRelatedElements() as $element) {
|
||||
if ($element->isSelected()) {
|
||||
$selectedElement[] = $element;
|
||||
|
||||
if (!$this->isMultiple()) {
|
||||
return $selectedElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $selectedElement;
|
||||
}
|
||||
|
||||
public function getFirstSelectedOption()
|
||||
{
|
||||
foreach ($this->getRelatedElements() as $element) {
|
||||
if ($element->isSelected()) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
throw new NoSuchElementException(
|
||||
sprintf('No %s are selected', $this->type === 'radio' ? 'radio buttons' : 'checkboxes')
|
||||
);
|
||||
}
|
||||
|
||||
public function selectByIndex($index)
|
||||
{
|
||||
$this->byIndex($index);
|
||||
}
|
||||
|
||||
public function selectByValue($value)
|
||||
{
|
||||
$this->byValue($value);
|
||||
}
|
||||
|
||||
public function selectByVisibleText($text)
|
||||
{
|
||||
$this->byVisibleText($text);
|
||||
}
|
||||
|
||||
public function selectByVisiblePartialText($text)
|
||||
{
|
||||
$this->byVisibleText($text, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects or deselects a checkbox or a radio button by its value.
|
||||
*
|
||||
* @param string $value
|
||||
* @param bool $select
|
||||
* @throws NoSuchElementException
|
||||
*/
|
||||
protected function byValue($value, $select = true)
|
||||
{
|
||||
$matched = false;
|
||||
foreach ($this->getRelatedElements($value) as $element) {
|
||||
$select ? $this->selectOption($element) : $this->deselectOption($element);
|
||||
if (!$this->isMultiple()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$matched = true;
|
||||
}
|
||||
|
||||
if (!$matched) {
|
||||
throw new NoSuchElementException(
|
||||
sprintf('Cannot locate %s with value: %s', $this->type, $value)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects or deselects a checkbox or a radio button by its index.
|
||||
*
|
||||
* @param int $index
|
||||
* @param bool $select
|
||||
* @throws NoSuchElementException
|
||||
*/
|
||||
protected function byIndex($index, $select = true)
|
||||
{
|
||||
$elements = $this->getRelatedElements();
|
||||
if (!isset($elements[$index])) {
|
||||
throw new NoSuchElementException(sprintf('Cannot locate %s with index: %d', $this->type, $index));
|
||||
}
|
||||
|
||||
$select ? $this->selectOption($elements[$index]) : $this->deselectOption($elements[$index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects or deselects a checkbox or a radio button by its visible text.
|
||||
*
|
||||
* @param string $text
|
||||
* @param bool $partial
|
||||
* @param bool $select
|
||||
*/
|
||||
protected function byVisibleText($text, $partial = false, $select = true)
|
||||
{
|
||||
foreach ($this->getRelatedElements() as $element) {
|
||||
$normalizeFilter = sprintf(
|
||||
$partial ? 'contains(normalize-space(.), %s)' : 'normalize-space(.) = %s',
|
||||
XPathEscaper::escapeQuotes($text)
|
||||
);
|
||||
|
||||
$xpath = 'ancestor::label';
|
||||
$xpathNormalize = sprintf('%s[%s]', $xpath, $normalizeFilter);
|
||||
|
||||
$id = $element->getAttribute('id');
|
||||
if ($id !== null) {
|
||||
$idFilter = sprintf('@for = %s', XPathEscaper::escapeQuotes($id));
|
||||
|
||||
$xpath .= sprintf(' | //label[%s]', $idFilter);
|
||||
$xpathNormalize .= sprintf(' | //label[%s and %s]', $idFilter, $normalizeFilter);
|
||||
}
|
||||
|
||||
try {
|
||||
$element->findElement(WebDriverBy::xpath($xpathNormalize));
|
||||
} catch (NoSuchElementException $e) {
|
||||
if ($partial) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// Since the mechanism of getting the text in xpath is not the same as
|
||||
// webdriver, use the expensive getText() to check if nothing is matched.
|
||||
if ($text !== $element->findElement(WebDriverBy::xpath($xpath))->getText()) {
|
||||
continue;
|
||||
}
|
||||
} catch (NoSuchElementException $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$select ? $this->selectOption($element) : $this->deselectOption($element);
|
||||
if (!$this->isMultiple()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets checkboxes or radio buttons with the same name.
|
||||
*
|
||||
* @param string|null $value
|
||||
* @return WebDriverElement[]
|
||||
*/
|
||||
protected function getRelatedElements($value = null)
|
||||
{
|
||||
$valueSelector = $value ? sprintf(' and @value = %s', XPathEscaper::escapeQuotes($value)) : '';
|
||||
$formId = $this->element->getAttribute('form');
|
||||
if ($formId === null) {
|
||||
$form = $this->element->findElement(WebDriverBy::xpath('ancestor::form'));
|
||||
|
||||
$formId = $form->getAttribute('id');
|
||||
if ($formId === '' || $formId === null) {
|
||||
return $form->findElements(WebDriverBy::xpath(
|
||||
sprintf('.//input[@name = %s%s]', XPathEscaper::escapeQuotes($this->name), $valueSelector)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#form
|
||||
return $this->element->findElements(
|
||||
WebDriverBy::xpath(sprintf(
|
||||
'//form[@id = %1$s]//input[@name = %2$s%3$s'
|
||||
. ' and ((boolean(@form) = true() and @form = %1$s) or boolean(@form) = false())]'
|
||||
. ' | //input[@form = %1$s and @name = %2$s%3$s]',
|
||||
XPathEscaper::escapeQuotes($formId),
|
||||
XPathEscaper::escapeQuotes($this->name),
|
||||
$valueSelector
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects a checkbox or a radio button.
|
||||
*/
|
||||
protected function selectOption(WebDriverElement $element)
|
||||
{
|
||||
if (!$element->isSelected()) {
|
||||
$element->click();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselects a checkbox or a radio button.
|
||||
*/
|
||||
protected function deselectOption(WebDriverElement $element)
|
||||
{
|
||||
if ($element->isSelected()) {
|
||||
$element->click();
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Chrome;
|
||||
|
||||
use Facebook\WebDriver\Remote\RemoteWebDriver;
|
||||
|
||||
/**
|
||||
* Provide access to Chrome DevTools Protocol (CDP) commands via HTTP endpoint of Chromedriver.
|
||||
*
|
||||
* @see https://chromedevtools.github.io/devtools-protocol/
|
||||
*/
|
||||
class ChromeDevToolsDriver
|
||||
{
|
||||
const SEND_COMMAND = [
|
||||
'method' => 'POST',
|
||||
'url' => '/session/:sessionId/goog/cdp/execute',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var RemoteWebDriver
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
public function __construct(RemoteWebDriver $driver)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a Chrome DevTools command
|
||||
*
|
||||
* @param string $command The DevTools command to execute
|
||||
* @param array $parameters Optional parameters to the command
|
||||
* @return array The result of the command
|
||||
*/
|
||||
public function execute($command, array $parameters = [])
|
||||
{
|
||||
$params = ['cmd' => $command, 'params' => (object) $parameters];
|
||||
|
||||
return $this->driver->executeCustomCommand(
|
||||
self::SEND_COMMAND['url'],
|
||||
self::SEND_COMMAND['method'],
|
||||
$params
|
||||
);
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Chrome;
|
||||
|
||||
use Facebook\WebDriver\Local\LocalWebDriver;
|
||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||
use Facebook\WebDriver\Remote\Service\DriverCommandExecutor;
|
||||
use Facebook\WebDriver\Remote\WebDriverCommand;
|
||||
|
||||
class ChromeDriver extends LocalWebDriver
|
||||
{
|
||||
/** @var ChromeDevToolsDriver */
|
||||
private $devTools;
|
||||
|
||||
/**
|
||||
* Creates a new ChromeDriver using default configuration.
|
||||
* This includes starting a new chromedriver process each time this method is called. However this may be
|
||||
* unnecessary overhead - instead, you can start the process once using ChromeDriverService and pass
|
||||
* this instance to startUsingDriverService() method.
|
||||
*
|
||||
* @todo Remove $service parameter. Use `ChromeDriver::startUsingDriverService` to pass custom $service instance.
|
||||
* @return static
|
||||
*/
|
||||
public static function start(DesiredCapabilities $desired_capabilities = null, ChromeDriverService $service = null)
|
||||
{
|
||||
if ($service === null) { // TODO: Remove the condition (always create default service)
|
||||
$service = ChromeDriverService::createDefaultService();
|
||||
}
|
||||
|
||||
return static::startUsingDriverService($service, $desired_capabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ChromeDriver using given ChromeDriverService.
|
||||
* This is usable when you for example don't want to start new chromedriver process for each individual test
|
||||
* and want to reuse the already started chromedriver, which will lower the overhead associated with spinning up
|
||||
* a new process.
|
||||
|
||||
* @return static
|
||||
*/
|
||||
public static function startUsingDriverService(
|
||||
ChromeDriverService $service,
|
||||
DesiredCapabilities $capabilities = null
|
||||
) {
|
||||
if ($capabilities === null) {
|
||||
$capabilities = DesiredCapabilities::chrome();
|
||||
}
|
||||
|
||||
$executor = new DriverCommandExecutor($service);
|
||||
$newSessionCommand = WebDriverCommand::newSession(
|
||||
[
|
||||
'capabilities' => [
|
||||
'firstMatch' => [(object) $capabilities->toW3cCompatibleArray()],
|
||||
],
|
||||
'desiredCapabilities' => (object) $capabilities->toArray(),
|
||||
]
|
||||
);
|
||||
|
||||
$response = $executor->execute($newSessionCommand);
|
||||
|
||||
/*
|
||||
* TODO: in next major version we may not need to use this method, because without OSS compatibility the
|
||||
* driver creation is straightforward.
|
||||
*/
|
||||
return static::createFromResponse($response, $executor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Remove in next major version. The class is internally no longer used and is kept only to keep BC.
|
||||
* @deprecated Use start or startUsingDriverService method instead.
|
||||
* @codeCoverageIgnore
|
||||
* @internal
|
||||
*/
|
||||
public function startSession(DesiredCapabilities $desired_capabilities)
|
||||
{
|
||||
$command = WebDriverCommand::newSession(
|
||||
[
|
||||
'capabilities' => [
|
||||
'firstMatch' => [(object) $desired_capabilities->toW3cCompatibleArray()],
|
||||
],
|
||||
'desiredCapabilities' => (object) $desired_capabilities->toArray(),
|
||||
]
|
||||
);
|
||||
$response = $this->executor->execute($command);
|
||||
$value = $response->getValue();
|
||||
|
||||
if (!$this->isW3cCompliant = isset($value['capabilities'])) {
|
||||
$this->executor->disableW3cCompliance();
|
||||
}
|
||||
|
||||
$this->sessionID = $response->getSessionID();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ChromeDevToolsDriver
|
||||
*/
|
||||
public function getDevTools()
|
||||
{
|
||||
if ($this->devTools === null) {
|
||||
$this->devTools = new ChromeDevToolsDriver($this);
|
||||
}
|
||||
|
||||
return $this->devTools;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Chrome;
|
||||
|
||||
use Facebook\WebDriver\Remote\Service\DriverService;
|
||||
|
||||
class ChromeDriverService extends DriverService
|
||||
{
|
||||
/**
|
||||
* The environment variable storing the path to the chrome driver executable.
|
||||
* @deprecated Use ChromeDriverService::CHROME_DRIVER_EXECUTABLE
|
||||
*/
|
||||
const CHROME_DRIVER_EXE_PROPERTY = 'webdriver.chrome.driver';
|
||||
/** @var string The environment variable storing the path to the chrome driver executable */
|
||||
const CHROME_DRIVER_EXECUTABLE = 'WEBDRIVER_CHROME_DRIVER';
|
||||
/**
|
||||
* @var string Default executable used when no other is provided
|
||||
* @internal
|
||||
*/
|
||||
const DEFAULT_EXECUTABLE = 'chromedriver';
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public static function createDefaultService()
|
||||
{
|
||||
$pathToExecutable = getenv(self::CHROME_DRIVER_EXECUTABLE) ?: getenv(self::CHROME_DRIVER_EXE_PROPERTY);
|
||||
if ($pathToExecutable === false || $pathToExecutable === '') {
|
||||
$pathToExecutable = static::DEFAULT_EXECUTABLE;
|
||||
}
|
||||
|
||||
$port = 9515; // TODO: Get another port if the default port is used.
|
||||
$args = ['--port=' . $port];
|
||||
|
||||
return new static($pathToExecutable, $port, $args);
|
||||
}
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Chrome;
|
||||
|
||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||
use JsonSerializable;
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* The class manages the capabilities in ChromeDriver.
|
||||
*
|
||||
* @see https://sites.google.com/a/chromium.org/chromedriver/capabilities
|
||||
*/
|
||||
class ChromeOptions implements JsonSerializable
|
||||
{
|
||||
/**
|
||||
* The key of chromeOptions in desired capabilities (in legacy OSS JsonWire protocol)
|
||||
* @todo Replace value with 'goog:chromeOptions' after JsonWire protocol support is removed
|
||||
*/
|
||||
const CAPABILITY = 'chromeOptions';
|
||||
/**
|
||||
* The key of chromeOptions in desired capabilities (in W3C compatible protocol)
|
||||
*/
|
||||
const CAPABILITY_W3C = 'goog:chromeOptions';
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $arguments = [];
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $binary = '';
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $extensions = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $experimentalOptions = [];
|
||||
|
||||
/**
|
||||
* Return a version of the class which can JSON serialized.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path of the Chrome executable. The path should be either absolute
|
||||
* or relative to the location running ChromeDriver server.
|
||||
*
|
||||
* @param string $path
|
||||
* @return ChromeOptions
|
||||
*/
|
||||
public function setBinary($path)
|
||||
{
|
||||
$this->binary = $path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arguments
|
||||
* @return ChromeOptions
|
||||
*/
|
||||
public function addArguments(array $arguments)
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $arguments);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Chrome extension to install on browser startup. Each path should be
|
||||
* a packed Chrome extension.
|
||||
*
|
||||
* @param array $paths
|
||||
* @return ChromeOptions
|
||||
*/
|
||||
public function addExtensions(array $paths)
|
||||
{
|
||||
foreach ($paths as $path) {
|
||||
$this->addExtension($path);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $encoded_extensions An array of base64 encoded of the extensions.
|
||||
* @return ChromeOptions
|
||||
*/
|
||||
public function addEncodedExtensions(array $encoded_extensions)
|
||||
{
|
||||
foreach ($encoded_extensions as $encoded_extension) {
|
||||
$this->addEncodedExtension($encoded_extension);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an experimental option which has not exposed officially.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return ChromeOptions
|
||||
*/
|
||||
public function setExperimentalOption($name, $value)
|
||||
{
|
||||
$this->experimentalOptions[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DesiredCapabilities The DesiredCapabilities for Chrome with this options.
|
||||
*/
|
||||
public function toCapabilities()
|
||||
{
|
||||
$capabilities = DesiredCapabilities::chrome();
|
||||
$capabilities->setCapability(self::CAPABILITY, $this);
|
||||
|
||||
return $capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \ArrayObject|array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
// The selenium server expects a 'dictionary' instead of a 'list' when
|
||||
// reading the chrome option. However, an empty array in PHP will be
|
||||
// converted to a 'list' instead of a 'dictionary'. To fix it, we work
|
||||
// with `ArrayObject`
|
||||
$options = new \ArrayObject($this->experimentalOptions);
|
||||
|
||||
if (!empty($this->binary)) {
|
||||
$options['binary'] = $this->binary;
|
||||
}
|
||||
|
||||
if (!empty($this->arguments)) {
|
||||
$options['args'] = $this->arguments;
|
||||
}
|
||||
|
||||
if (!empty($this->extensions)) {
|
||||
$options['extensions'] = $this->extensions;
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Chrome extension to install on browser startup. Each path should be a
|
||||
* packed Chrome extension.
|
||||
*
|
||||
* @param string $path
|
||||
* @return ChromeOptions
|
||||
*/
|
||||
private function addExtension($path)
|
||||
{
|
||||
$this->addEncodedExtension(base64_encode(file_get_contents($path)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encoded_extension Base64 encoded of the extension.
|
||||
* @return ChromeOptions
|
||||
*/
|
||||
private function addEncodedExtension($encoded_extension)
|
||||
{
|
||||
$this->extensions[] = $encoded_extension;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Set values of an cookie.
|
||||
*
|
||||
* Implements ArrayAccess for backwards compatibility.
|
||||
*
|
||||
* @see https://w3c.github.io/webdriver/webdriver-spec.html#cookies
|
||||
*/
|
||||
class Cookie implements \ArrayAccess
|
||||
{
|
||||
/** @var array */
|
||||
protected $cookie = [];
|
||||
|
||||
/**
|
||||
* @param string $name The name of the cookie; may not be null or an empty string.
|
||||
* @param string $value The cookie value; may not be null.
|
||||
*/
|
||||
public function __construct($name, $value)
|
||||
{
|
||||
$this->validateCookieName($name);
|
||||
$this->validateCookieValue($value);
|
||||
|
||||
$this->cookie['name'] = $name;
|
||||
$this->cookie['value'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $cookieArray The cookie fields; must contain name and value.
|
||||
* @return Cookie
|
||||
*/
|
||||
public static function createFromArray(array $cookieArray)
|
||||
{
|
||||
if (!isset($cookieArray['name'])) {
|
||||
throw new InvalidArgumentException('Cookie name should be set');
|
||||
}
|
||||
if (!isset($cookieArray['value'])) {
|
||||
throw new InvalidArgumentException('Cookie value should be set');
|
||||
}
|
||||
$cookie = new self($cookieArray['name'], $cookieArray['value']);
|
||||
|
||||
if (isset($cookieArray['path'])) {
|
||||
$cookie->setPath($cookieArray['path']);
|
||||
}
|
||||
if (isset($cookieArray['domain'])) {
|
||||
$cookie->setDomain($cookieArray['domain']);
|
||||
}
|
||||
if (isset($cookieArray['expiry'])) {
|
||||
$cookie->setExpiry($cookieArray['expiry']);
|
||||
}
|
||||
if (isset($cookieArray['secure'])) {
|
||||
$cookie->setSecure($cookieArray['secure']);
|
||||
}
|
||||
if (isset($cookieArray['httpOnly'])) {
|
||||
$cookie->setHttpOnly($cookieArray['httpOnly']);
|
||||
}
|
||||
if (isset($cookieArray['sameSite'])) {
|
||||
$cookie->setSameSite($cookieArray['sameSite']);
|
||||
}
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->offsetGet('name');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->offsetGet('value');
|
||||
}
|
||||
|
||||
/**
|
||||
* The path the cookie is visible to. Defaults to "/" if omitted.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function setPath($path)
|
||||
{
|
||||
$this->offsetSet('path', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->offsetGet('path');
|
||||
}
|
||||
|
||||
/**
|
||||
* The domain the cookie is visible to. Defaults to the current browsing context's document's URL domain if omitted.
|
||||
*
|
||||
* @param string $domain
|
||||
*/
|
||||
public function setDomain($domain)
|
||||
{
|
||||
if (mb_strpos($domain, ':') !== false) {
|
||||
throw new InvalidArgumentException(sprintf('Cookie domain "%s" should not contain a port', $domain));
|
||||
}
|
||||
|
||||
$this->offsetSet('domain', $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getDomain()
|
||||
{
|
||||
return $this->offsetGet('domain');
|
||||
}
|
||||
|
||||
/**
|
||||
* The cookie's expiration date, specified in seconds since Unix Epoch.
|
||||
*
|
||||
* @param int $expiry
|
||||
*/
|
||||
public function setExpiry($expiry)
|
||||
{
|
||||
$this->offsetSet('expiry', (int) $expiry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function getExpiry()
|
||||
{
|
||||
return $this->offsetGet('expiry');
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this cookie requires a secure connection (https). Defaults to false if omitted.
|
||||
*
|
||||
* @param bool $secure
|
||||
*/
|
||||
public function setSecure($secure)
|
||||
{
|
||||
$this->offsetSet('secure', $secure);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isSecure()
|
||||
{
|
||||
return $this->offsetGet('secure');
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the cookie is an HTTP only cookie. Defaults to false if omitted.
|
||||
*
|
||||
* @param bool $httpOnly
|
||||
*/
|
||||
public function setHttpOnly($httpOnly)
|
||||
{
|
||||
$this->offsetSet('httpOnly', $httpOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|null
|
||||
*/
|
||||
public function isHttpOnly()
|
||||
{
|
||||
return $this->offsetGet('httpOnly');
|
||||
}
|
||||
|
||||
/**
|
||||
* The cookie's same-site value.
|
||||
*
|
||||
* @param string $sameSite
|
||||
*/
|
||||
public function setSameSite($sameSite)
|
||||
{
|
||||
$this->offsetSet('sameSite', $sameSite);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSameSite()
|
||||
{
|
||||
return $this->offsetGet('sameSite');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$cookie = $this->cookie;
|
||||
if (!isset($cookie['secure'])) {
|
||||
// Passing a boolean value for the "secure" flag is mandatory when using geckodriver
|
||||
$cookie['secure'] = false;
|
||||
}
|
||||
|
||||
return $cookie;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->cookie[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return mixed
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return $this->offsetExists($offset) ? $this->cookie[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
unset($this->cookie[$offset]);
|
||||
} else {
|
||||
$this->cookie[$offset] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->cookie[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
protected function validateCookieName($name)
|
||||
{
|
||||
if ($name === null || $name === '') {
|
||||
throw new InvalidArgumentException('Cookie name should be non-empty');
|
||||
}
|
||||
|
||||
if (mb_strpos($name, ';') !== false) {
|
||||
throw new InvalidArgumentException('Cookie name should not contain a ";"');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
*/
|
||||
protected function validateCookieValue($value)
|
||||
{
|
||||
if ($value === null) {
|
||||
throw new InvalidArgumentException('Cookie value is required when setting a cookie');
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* The driver server process is unexpectedly no longer available.
|
||||
*/
|
||||
class DriverServerDiedException extends WebDriverException
|
||||
{
|
||||
public function __construct(\Exception $previous = null)
|
||||
{
|
||||
parent::__construct('The driver server has died.');
|
||||
\Exception::__construct($this->getMessage(), $this->getCode(), $previous);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* The Element Click command could not be completed because the element receiving the events is obscuring the element
|
||||
* that was requested clicked.
|
||||
*/
|
||||
class ElementClickInterceptedException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A command could not be completed because the element is not pointer- or keyboard interactable.
|
||||
*/
|
||||
class ElementNotInteractableException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Use Facebook\WebDriver\Exception\ElementNotInteractableException
|
||||
*/
|
||||
class ElementNotSelectableException extends ElementNotInteractableException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class ElementNotVisibleException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class ExpectedException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class IMEEngineActivationFailedException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class IMENotAvailableException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class IndexOutOfBoundsException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* Navigation caused the user agent to hit a certificate warning, which is usually the result of an expired
|
||||
* or invalid TLS certificate.
|
||||
*/
|
||||
class InsecureCertificateException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* The arguments passed to a command are either invalid or malformed.
|
||||
*/
|
||||
class InvalidArgumentException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* An illegal attempt was made to set a cookie under a different domain than the current page.
|
||||
*/
|
||||
class InvalidCookieDomainException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class InvalidCoordinatesException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A command could not be completed because the element is in an invalid state, e.g. attempting to clear an element
|
||||
* that isn’t both editable and resettable.
|
||||
*/
|
||||
class InvalidElementStateException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* Argument was an invalid selector.
|
||||
*/
|
||||
class InvalidSelectorException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* Occurs if the given session id is not in the list of active sessions, meaning the session either does not exist
|
||||
* or that it’s not active.
|
||||
*/
|
||||
class InvalidSessionIdException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* An error occurred while executing JavaScript supplied by the user.
|
||||
*/
|
||||
class JavascriptErrorException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* The target for mouse interaction is not in the browser’s viewport and cannot be brought into that viewport.
|
||||
*/
|
||||
class MoveTargetOutOfBoundsException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Use Facebook\WebDriver\Exception\NoSuchAlertException
|
||||
*/
|
||||
class NoAlertOpenException extends NoSuchAlertException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NoCollectionException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NoScriptResultException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NoStringException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NoStringLengthException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NoStringWrapperException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* An attempt was made to operate on a modal dialog when one was not open.
|
||||
*/
|
||||
class NoSuchAlertException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NoSuchCollectionException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* No cookie matching the given path name was found amongst the associated cookies of the current browsing context’s
|
||||
* active document.
|
||||
*/
|
||||
class NoSuchCookieException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Use Facebook\WebDriver\Exception\NoSuchWindowException
|
||||
*/
|
||||
class NoSuchDocumentException extends NoSuchWindowException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NoSuchDriverException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* An element could not be located on the page using the given search parameters.
|
||||
*/
|
||||
class NoSuchElementException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A command to switch to a frame could not be satisfied because the frame could not be found.
|
||||
*/
|
||||
class NoSuchFrameException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A command to switch to a window could not be satisfied because the window could not be found.
|
||||
*/
|
||||
class NoSuchWindowException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class NullPointerException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A script did not complete before its timeout expired.
|
||||
*/
|
||||
class ScriptTimeoutException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A new session could not be created.
|
||||
*/
|
||||
class SessionNotCreatedException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A command failed because the referenced element is no longer attached to the DOM.
|
||||
*/
|
||||
class StaleElementReferenceException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* An operation did not complete before its timeout expired.
|
||||
*/
|
||||
class TimeoutException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A screen capture was made impossible.
|
||||
*/
|
||||
class UnableToCaptureScreenException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A command to set a cookie’s value could not be satisfied.
|
||||
*/
|
||||
class UnableToSetCookieException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A modal dialog was open, blocking this operation.
|
||||
*/
|
||||
class UnexpectedAlertOpenException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Use Facebook\WebDriver\Exception\JavascriptErrorException
|
||||
*/
|
||||
class UnexpectedJavascriptException extends JavascriptErrorException
|
||||
{
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
class UnexpectedTagNameException extends WebDriverException
|
||||
{
|
||||
/**
|
||||
* @param string $expected_tag_name
|
||||
* @param string $actual_tag_name
|
||||
*/
|
||||
public function __construct(
|
||||
$expected_tag_name,
|
||||
$actual_tag_name
|
||||
) {
|
||||
parent::__construct(
|
||||
sprintf(
|
||||
'Element should have been "%s" but was "%s"',
|
||||
$expected_tag_name,
|
||||
$actual_tag_name
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* A command could not be executed because the remote end is not aware of it.
|
||||
*/
|
||||
class UnknownCommandException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* An unknown error occurred in the remote end while processing the command.
|
||||
*/
|
||||
class UnknownErrorException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* The requested command matched a known URL but did not match an method for that URL.
|
||||
*/
|
||||
class UnknownMethodException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Use Facebook\WebDriver\Exception\UnknownErrorException
|
||||
*/
|
||||
class UnknownServerException extends UnknownErrorException
|
||||
{
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
class UnrecognizedExceptionException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* Indicates that a command that should have executed properly cannot be supported for some reason.
|
||||
*/
|
||||
class UnsupportedOperationException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
class WebDriverCurlException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* @see https://w3c.github.io/webdriver/#errors
|
||||
*/
|
||||
class WebDriverException extends Exception
|
||||
{
|
||||
private $results;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param mixed $results
|
||||
*/
|
||||
public function __construct($message, $results = null)
|
||||
{
|
||||
parent::__construct($message);
|
||||
$this->results = $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getResults()
|
||||
{
|
||||
return $this->results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw WebDriverExceptions based on WebDriver status code.
|
||||
*
|
||||
* @param int|string $status_code
|
||||
* @param string $message
|
||||
* @param mixed $results
|
||||
*
|
||||
* @throws ElementClickInterceptedException
|
||||
* @throws ElementNotInteractableException
|
||||
* @throws ElementNotSelectableException
|
||||
* @throws ElementNotVisibleException
|
||||
* @throws ExpectedException
|
||||
* @throws IMEEngineActivationFailedException
|
||||
* @throws IMENotAvailableException
|
||||
* @throws IndexOutOfBoundsException
|
||||
* @throws InsecureCertificateException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws InvalidCookieDomainException
|
||||
* @throws InvalidCoordinatesException
|
||||
* @throws InvalidElementStateException
|
||||
* @throws InvalidSelectorException
|
||||
* @throws InvalidSessionIdException
|
||||
* @throws JavascriptErrorException
|
||||
* @throws MoveTargetOutOfBoundsException
|
||||
* @throws NoAlertOpenException
|
||||
* @throws NoCollectionException
|
||||
* @throws NoScriptResultException
|
||||
* @throws NoStringException
|
||||
* @throws NoStringLengthException
|
||||
* @throws NoStringWrapperException
|
||||
* @throws NoSuchAlertException
|
||||
* @throws NoSuchCollectionException
|
||||
* @throws NoSuchCookieException
|
||||
* @throws NoSuchDocumentException
|
||||
* @throws NoSuchDriverException
|
||||
* @throws NoSuchElementException
|
||||
* @throws NoSuchFrameException
|
||||
* @throws NoSuchWindowException
|
||||
* @throws NullPointerException
|
||||
* @throws ScriptTimeoutException
|
||||
* @throws SessionNotCreatedException
|
||||
* @throws StaleElementReferenceException
|
||||
* @throws TimeoutException
|
||||
* @throws UnableToCaptureScreenException
|
||||
* @throws UnableToSetCookieException
|
||||
* @throws UnexpectedAlertOpenException
|
||||
* @throws UnexpectedJavascriptException
|
||||
* @throws UnknownCommandException
|
||||
* @throws UnknownErrorException
|
||||
* @throws UnknownMethodException
|
||||
* @throws UnknownServerException
|
||||
* @throws UnrecognizedExceptionException
|
||||
* @throws UnsupportedOperationException
|
||||
* @throws XPathLookupException
|
||||
*/
|
||||
public static function throwException($status_code, $message, $results)
|
||||
{
|
||||
if (is_string($status_code)) {
|
||||
// @see https://w3c.github.io/webdriver/#errors
|
||||
switch ($status_code) {
|
||||
case 'element click intercepted':
|
||||
throw new ElementClickInterceptedException($message, $results);
|
||||
case 'element not interactable':
|
||||
throw new ElementNotInteractableException($message, $results);
|
||||
case 'insecure certificate':
|
||||
throw new InsecureCertificateException($message, $results);
|
||||
case 'invalid argument':
|
||||
throw new InvalidArgumentException($message, $results);
|
||||
case 'invalid cookie domain':
|
||||
throw new InvalidCookieDomainException($message, $results);
|
||||
case 'invalid element state':
|
||||
throw new InvalidElementStateException($message, $results);
|
||||
case 'invalid selector':
|
||||
throw new InvalidSelectorException($message, $results);
|
||||
case 'invalid session id':
|
||||
throw new InvalidSessionIdException($message, $results);
|
||||
case 'javascript error':
|
||||
throw new JavascriptErrorException($message, $results);
|
||||
case 'move target out of bounds':
|
||||
throw new MoveTargetOutOfBoundsException($message, $results);
|
||||
case 'no such alert':
|
||||
throw new NoSuchAlertException($message, $results);
|
||||
case 'no such cookie':
|
||||
throw new NoSuchCookieException($message, $results);
|
||||
case 'no such element':
|
||||
throw new NoSuchElementException($message, $results);
|
||||
case 'no such frame':
|
||||
throw new NoSuchFrameException($message, $results);
|
||||
case 'no such window':
|
||||
throw new NoSuchWindowException($message, $results);
|
||||
case 'script timeout':
|
||||
throw new ScriptTimeoutException($message, $results);
|
||||
case 'session not created':
|
||||
throw new SessionNotCreatedException($message, $results);
|
||||
case 'stale element reference':
|
||||
throw new StaleElementReferenceException($message, $results);
|
||||
case 'timeout':
|
||||
throw new TimeoutException($message, $results);
|
||||
case 'unable to set cookie':
|
||||
throw new UnableToSetCookieException($message, $results);
|
||||
case 'unable to capture screen':
|
||||
throw new UnableToCaptureScreenException($message, $results);
|
||||
case 'unexpected alert open':
|
||||
throw new UnexpectedAlertOpenException($message, $results);
|
||||
case 'unknown command':
|
||||
throw new UnknownCommandException($message, $results);
|
||||
case 'unknown error':
|
||||
throw new UnknownErrorException($message, $results);
|
||||
case 'unknown method':
|
||||
throw new UnknownMethodException($message, $results);
|
||||
case 'unsupported operation':
|
||||
throw new UnsupportedOperationException($message, $results);
|
||||
default:
|
||||
throw new UnrecognizedExceptionException($message, $results);
|
||||
}
|
||||
}
|
||||
|
||||
switch ($status_code) {
|
||||
case 1:
|
||||
throw new IndexOutOfBoundsException($message, $results);
|
||||
case 2:
|
||||
throw new NoCollectionException($message, $results);
|
||||
case 3:
|
||||
throw new NoStringException($message, $results);
|
||||
case 4:
|
||||
throw new NoStringLengthException($message, $results);
|
||||
case 5:
|
||||
throw new NoStringWrapperException($message, $results);
|
||||
case 6:
|
||||
throw new NoSuchDriverException($message, $results);
|
||||
case 7:
|
||||
throw new NoSuchElementException($message, $results);
|
||||
case 8:
|
||||
throw new NoSuchFrameException($message, $results);
|
||||
case 9:
|
||||
throw new UnknownCommandException($message, $results);
|
||||
case 10:
|
||||
throw new StaleElementReferenceException($message, $results);
|
||||
case 11:
|
||||
throw new ElementNotVisibleException($message, $results);
|
||||
case 12:
|
||||
throw new InvalidElementStateException($message, $results);
|
||||
case 13:
|
||||
throw new UnknownServerException($message, $results);
|
||||
case 14:
|
||||
throw new ExpectedException($message, $results);
|
||||
case 15:
|
||||
throw new ElementNotSelectableException($message, $results);
|
||||
case 16:
|
||||
throw new NoSuchDocumentException($message, $results);
|
||||
case 17:
|
||||
throw new UnexpectedJavascriptException($message, $results);
|
||||
case 18:
|
||||
throw new NoScriptResultException($message, $results);
|
||||
case 19:
|
||||
throw new XPathLookupException($message, $results);
|
||||
case 20:
|
||||
throw new NoSuchCollectionException($message, $results);
|
||||
case 21:
|
||||
throw new TimeoutException($message, $results);
|
||||
case 22:
|
||||
throw new NullPointerException($message, $results);
|
||||
case 23:
|
||||
throw new NoSuchWindowException($message, $results);
|
||||
case 24:
|
||||
throw new InvalidCookieDomainException($message, $results);
|
||||
case 25:
|
||||
throw new UnableToSetCookieException($message, $results);
|
||||
case 26:
|
||||
throw new UnexpectedAlertOpenException($message, $results);
|
||||
case 27:
|
||||
throw new NoAlertOpenException($message, $results);
|
||||
case 28:
|
||||
throw new ScriptTimeoutException($message, $results);
|
||||
case 29:
|
||||
throw new InvalidCoordinatesException($message, $results);
|
||||
case 30:
|
||||
throw new IMENotAvailableException($message, $results);
|
||||
case 31:
|
||||
throw new IMEEngineActivationFailedException($message, $results);
|
||||
case 32:
|
||||
throw new InvalidSelectorException($message, $results);
|
||||
case 33:
|
||||
throw new SessionNotCreatedException($message, $results);
|
||||
case 34:
|
||||
throw new MoveTargetOutOfBoundsException($message, $results);
|
||||
default:
|
||||
throw new UnrecognizedExceptionException($message, $results);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Exception;
|
||||
|
||||
/**
|
||||
* @deprecated Removed in W3C WebDriver, see https://github.com/php-webdriver/php-webdriver/pull/686
|
||||
*/
|
||||
class XPathLookupException extends WebDriverException
|
||||
{
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Firefox;
|
||||
|
||||
use Facebook\WebDriver\Local\LocalWebDriver;
|
||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||
use Facebook\WebDriver\Remote\Service\DriverCommandExecutor;
|
||||
use Facebook\WebDriver\Remote\WebDriverCommand;
|
||||
|
||||
class FirefoxDriver extends LocalWebDriver
|
||||
{
|
||||
const PROFILE = 'firefox_profile';
|
||||
|
||||
/**
|
||||
* Creates a new FirefoxDriver using default configuration.
|
||||
* This includes starting a new geckodriver process each time this method is called. However this may be
|
||||
* unnecessary overhead - instead, you can start the process once using FirefoxDriverService and pass
|
||||
* this instance to startUsingDriverService() method.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function start(DesiredCapabilities $capabilities = null)
|
||||
{
|
||||
$service = FirefoxDriverService::createDefaultService();
|
||||
|
||||
return static::startUsingDriverService($service, $capabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new FirefoxDriver using given FirefoxDriverService.
|
||||
* This is usable when you for example don't want to start new geckodriver process for each individual test
|
||||
* and want to reuse the already started geckodriver, which will lower the overhead associated with spinning up
|
||||
* a new process.
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function startUsingDriverService(
|
||||
FirefoxDriverService $service,
|
||||
DesiredCapabilities $capabilities = null
|
||||
) {
|
||||
if ($capabilities === null) {
|
||||
$capabilities = DesiredCapabilities::firefox();
|
||||
}
|
||||
|
||||
$executor = new DriverCommandExecutor($service);
|
||||
$newSessionCommand = WebDriverCommand::newSession(
|
||||
[
|
||||
'capabilities' => [
|
||||
'firstMatch' => [(object) $capabilities->toW3cCompatibleArray()],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$response = $executor->execute($newSessionCommand);
|
||||
|
||||
$returnedCapabilities = DesiredCapabilities::createFromW3cCapabilities($response->getValue()['capabilities']);
|
||||
$sessionId = $response->getSessionID();
|
||||
|
||||
return new static($executor, $sessionId, $returnedCapabilities, true);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Firefox;
|
||||
|
||||
use Facebook\WebDriver\Remote\Service\DriverService;
|
||||
|
||||
class FirefoxDriverService extends DriverService
|
||||
{
|
||||
/**
|
||||
* @var string Name of the environment variable storing the path to the driver binary
|
||||
*/
|
||||
const WEBDRIVER_FIREFOX_DRIVER = 'WEBDRIVER_FIREFOX_DRIVER';
|
||||
/**
|
||||
* @var string Default executable used when no other is provided
|
||||
* @internal
|
||||
*/
|
||||
const DEFAULT_EXECUTABLE = 'geckodriver';
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public static function createDefaultService()
|
||||
{
|
||||
$pathToExecutable = getenv(static::WEBDRIVER_FIREFOX_DRIVER);
|
||||
if ($pathToExecutable === false || $pathToExecutable === '') {
|
||||
$pathToExecutable = static::DEFAULT_EXECUTABLE;
|
||||
}
|
||||
|
||||
$port = 9515; // TODO: Get another free port if the default port is used.
|
||||
$args = ['-p=' . $port];
|
||||
|
||||
return new static($pathToExecutable, $port, $args);
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Firefox;
|
||||
|
||||
use ReturnTypeWillChange;
|
||||
|
||||
/**
|
||||
* Class to manage Firefox-specific capabilities
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions
|
||||
*/
|
||||
class FirefoxOptions implements \JsonSerializable
|
||||
{
|
||||
/** @var string The key of FirefoxOptions in desired capabilities */
|
||||
const CAPABILITY = 'moz:firefoxOptions';
|
||||
/** @var string */
|
||||
const OPTION_ARGS = 'args';
|
||||
/** @var string */
|
||||
const OPTION_PREFS = 'prefs';
|
||||
|
||||
/** @var array */
|
||||
private $options = [];
|
||||
/** @var array */
|
||||
private $arguments = [];
|
||||
/** @var array */
|
||||
private $preferences = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Set default preferences:
|
||||
// disable the "Reader View" help tooltip, which can hide elements in the window.document
|
||||
$this->setPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED, false);
|
||||
// disable JSON viewer and let JSON be rendered as raw data
|
||||
$this->setPreference(FirefoxPreferences::DEVTOOLS_JSONVIEW, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly set firefoxOptions.
|
||||
* Use `addArguments` to add command line arguments and `setPreference` to set Firefox about:config entry.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return self
|
||||
*/
|
||||
public function setOption($name, $value)
|
||||
{
|
||||
if ($name === self::OPTION_PREFS) {
|
||||
throw new \InvalidArgumentException('Use setPreference() method to set Firefox preferences');
|
||||
}
|
||||
if ($name === self::OPTION_ARGS) {
|
||||
throw new \InvalidArgumentException('Use addArguments() method to add Firefox arguments');
|
||||
}
|
||||
|
||||
$this->options[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command line arguments to pass to the Firefox binary.
|
||||
* These must include the leading dash (-) where required, e.g. ['-headless'].
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions#args
|
||||
* @param string[] $arguments
|
||||
* @return self
|
||||
*/
|
||||
public function addArguments(array $arguments)
|
||||
{
|
||||
$this->arguments = array_merge($this->arguments, $arguments);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Firefox preference (about:config entry).
|
||||
*
|
||||
* @see http://kb.mozillazine.org/About:config_entries
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions#prefs
|
||||
* @param string $name
|
||||
* @param string|bool|int $value
|
||||
* @return self
|
||||
*/
|
||||
public function setPreference($name, $value)
|
||||
{
|
||||
$this->preferences[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$array = $this->options;
|
||||
if (!empty($this->arguments)) {
|
||||
$array[self::OPTION_ARGS] = $this->arguments;
|
||||
}
|
||||
if (!empty($this->preferences)) {
|
||||
$array[self::OPTION_PREFS] = $this->preferences;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return new \ArrayObject($this->toArray());
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Firefox;
|
||||
|
||||
/**
|
||||
* Constants of common Firefox profile preferences (about:config values).
|
||||
* @see http://kb.mozillazine.org/Firefox_:_FAQs_:_About:config_Entries
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class FirefoxPreferences
|
||||
{
|
||||
/** @var string Port WebDriver uses to communicate with Firefox instance */
|
||||
const WEBDRIVER_FIREFOX_PORT = 'webdriver_firefox_port';
|
||||
/** @var string Should the reader view (FF 38+) be enabled? */
|
||||
const READER_PARSE_ON_LOAD_ENABLED = 'reader.parse-on-load.enabled';
|
||||
/** @var string Browser homepage */
|
||||
const BROWSER_STARTUP_HOMEPAGE = 'browser.startup.homepage';
|
||||
/** @var string Should the Devtools JSON view be enabled? */
|
||||
const DEVTOOLS_JSONVIEW = 'devtools.jsonview.enabled';
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Firefox;
|
||||
|
||||
use Facebook\WebDriver\Exception\WebDriverException;
|
||||
use FilesystemIterator;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use ZipArchive;
|
||||
|
||||
class FirefoxProfile
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $preferences = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $extensions = [];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $extensions_datas = [];
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $rdf_file;
|
||||
|
||||
/**
|
||||
* @param string $extension The path to the xpi extension.
|
||||
* @return FirefoxProfile
|
||||
*/
|
||||
public function addExtension($extension)
|
||||
{
|
||||
$this->extensions[] = $extension;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extension_datas The path to the folder containing the datas to add to the extension
|
||||
* @return FirefoxProfile
|
||||
*/
|
||||
public function addExtensionDatas($extension_datas)
|
||||
{
|
||||
if (!is_dir($extension_datas)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->extensions_datas[basename($extension_datas)] = $extension_datas;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $rdf_file The path to the rdf file
|
||||
* @return FirefoxProfile
|
||||
*/
|
||||
public function setRdfFile($rdf_file)
|
||||
{
|
||||
if (!is_file($rdf_file)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->rdf_file = $rdf_file;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string|bool|int $value
|
||||
* @throws WebDriverException
|
||||
* @return FirefoxProfile
|
||||
*/
|
||||
public function setPreference($key, $value)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = sprintf('"%s"', $value);
|
||||
} else {
|
||||
if (is_int($value)) {
|
||||
$value = sprintf('%d', $value);
|
||||
} else {
|
||||
if (is_bool($value)) {
|
||||
$value = $value ? 'true' : 'false';
|
||||
} else {
|
||||
throw new WebDriverException(
|
||||
'The value of the preference should be either a string, int or bool.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->preferences[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPreference($key)
|
||||
{
|
||||
if (array_key_exists($key, $this->preferences)) {
|
||||
return $this->preferences[$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function encode()
|
||||
{
|
||||
$temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile');
|
||||
|
||||
if (isset($this->rdf_file)) {
|
||||
copy($this->rdf_file, $temp_dir . DIRECTORY_SEPARATOR . 'mimeTypes.rdf');
|
||||
}
|
||||
|
||||
foreach ($this->extensions as $extension) {
|
||||
$this->installExtension($extension, $temp_dir);
|
||||
}
|
||||
|
||||
foreach ($this->extensions_datas as $dirname => $extension_datas) {
|
||||
mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname);
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($extension_datas, RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
foreach ($iterator as $item) {
|
||||
$target_dir = $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR
|
||||
. $iterator->getSubPathName();
|
||||
|
||||
if ($item->isDir()) {
|
||||
mkdir($target_dir);
|
||||
} else {
|
||||
copy($item, $target_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content = '';
|
||||
foreach ($this->preferences as $key => $value) {
|
||||
$content .= sprintf("user_pref(\"%s\", %s);\n", $key, $value);
|
||||
}
|
||||
file_put_contents($temp_dir . '/user.js', $content);
|
||||
|
||||
// Intentionally do not use `tempnam()`, as it creates empty file which zip extension may not handle.
|
||||
$temp_zip = sys_get_temp_dir() . '/' . uniqid('WebDriverFirefoxProfileZip', false);
|
||||
|
||||
$zip = new ZipArchive();
|
||||
$zip->open($temp_zip, ZipArchive::CREATE);
|
||||
|
||||
$dir = new RecursiveDirectoryIterator($temp_dir);
|
||||
$files = new RecursiveIteratorIterator($dir);
|
||||
|
||||
$dir_prefix = preg_replace(
|
||||
'#\\\\#',
|
||||
'\\\\\\\\',
|
||||
$temp_dir . DIRECTORY_SEPARATOR
|
||||
);
|
||||
|
||||
foreach ($files as $name => $object) {
|
||||
if (is_dir($name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = preg_replace("#^{$dir_prefix}#", '', $name);
|
||||
$zip->addFile($name, $path);
|
||||
}
|
||||
$zip->close();
|
||||
|
||||
$profile = base64_encode(file_get_contents($temp_zip));
|
||||
|
||||
// clean up
|
||||
$this->deleteDirectory($temp_dir);
|
||||
unlink($temp_zip);
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $extension The path to the extension.
|
||||
* @param string $profile_dir The path to the profile directory.
|
||||
* @return string The path to the directory of this extension.
|
||||
*/
|
||||
private function installExtension($extension, $profile_dir)
|
||||
{
|
||||
$temp_dir = $this->createTempDirectory('WebDriverFirefoxProfileExtension');
|
||||
$this->extractTo($extension, $temp_dir);
|
||||
|
||||
// This is a hacky way to parse the id since there is no offical RDF parser library.
|
||||
// Find the correct namespace for the id element.
|
||||
$install_rdf_path = $temp_dir . '/install.rdf';
|
||||
$xml = simplexml_load_file($install_rdf_path);
|
||||
$ns = $xml->getDocNamespaces();
|
||||
$prefix = '';
|
||||
if (!empty($ns)) {
|
||||
foreach ($ns as $key => $value) {
|
||||
if (mb_strpos($value, '//www.mozilla.org/2004/em-rdf') > 0) {
|
||||
if ($key != '') {
|
||||
$prefix = $key . ':'; // Separate the namespace from the name.
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Get the extension id from the install manifest.
|
||||
$matches = [];
|
||||
preg_match('#<' . $prefix . 'id>([^<]+)</' . $prefix . 'id>#', $xml->asXML(), $matches);
|
||||
if (isset($matches[1])) {
|
||||
$ext_dir = $profile_dir . '/extensions/' . $matches[1];
|
||||
mkdir($ext_dir, 0777, true);
|
||||
$this->extractTo($extension, $ext_dir);
|
||||
} else {
|
||||
$this->deleteDirectory($temp_dir);
|
||||
|
||||
throw new WebDriverException('Cannot get the extension id from the install manifest.');
|
||||
}
|
||||
|
||||
$this->deleteDirectory($temp_dir);
|
||||
|
||||
return $ext_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prefix Prefix of the temp directory.
|
||||
*
|
||||
* @throws WebDriverException
|
||||
* @return string The path to the temp directory created.
|
||||
*/
|
||||
private function createTempDirectory($prefix = '')
|
||||
{
|
||||
$temp_dir = tempnam(sys_get_temp_dir(), $prefix);
|
||||
if (file_exists($temp_dir)) {
|
||||
unlink($temp_dir);
|
||||
mkdir($temp_dir);
|
||||
if (!is_dir($temp_dir)) {
|
||||
throw new WebDriverException('Cannot create firefox profile.');
|
||||
}
|
||||
}
|
||||
|
||||
return $temp_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory The path to the directory.
|
||||
*/
|
||||
private function deleteDirectory($directory)
|
||||
{
|
||||
$dir = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS);
|
||||
$paths = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if ($path->isDir() && !$path->isLink()) {
|
||||
rmdir($path->getPathname());
|
||||
} else {
|
||||
unlink($path->getPathname());
|
||||
}
|
||||
}
|
||||
|
||||
rmdir($directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $xpi The path to the .xpi extension.
|
||||
* @param string $target_dir The path to the unzip directory.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @return FirefoxProfile
|
||||
*/
|
||||
private function extractTo($xpi, $target_dir)
|
||||
{
|
||||
$zip = new ZipArchive();
|
||||
if (file_exists($xpi)) {
|
||||
if ($zip->open($xpi)) {
|
||||
$zip->extractTo($target_dir);
|
||||
$zip->close();
|
||||
} else {
|
||||
throw new \Exception("Failed to open the firefox extension. '$xpi'");
|
||||
}
|
||||
} else {
|
||||
throw new \Exception("Firefox extension doesn't exist. '$xpi'");
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
/**
|
||||
* Move to the location and then release the mouse key.
|
||||
*/
|
||||
class WebDriverButtonReleaseAction extends WebDriverMouseAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->mouse->mouseUp($this->getActionLocation());
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverClickAction extends WebDriverMouseAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->mouse->click($this->getActionLocation());
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
/**
|
||||
* Move the the location, click and hold.
|
||||
*/
|
||||
class WebDriverClickAndHoldAction extends WebDriverMouseAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->mouse->mouseDown($this->getActionLocation());
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
/**
|
||||
* You can call it 'Right Click' if you like.
|
||||
*/
|
||||
class WebDriverContextClickAction extends WebDriverMouseAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->mouse->contextClick($this->getActionLocation());
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\Exception\UnsupportedOperationException;
|
||||
use Facebook\WebDriver\WebDriverPoint;
|
||||
|
||||
/**
|
||||
* Interface representing basic mouse operations.
|
||||
*/
|
||||
class WebDriverCoordinates
|
||||
{
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $onScreen;
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $inViewPort;
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
private $onPage;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $auxiliary;
|
||||
|
||||
/**
|
||||
* @param null $on_screen
|
||||
* @param callable $in_view_port
|
||||
* @param callable $on_page
|
||||
* @param string $auxiliary
|
||||
*/
|
||||
public function __construct($on_screen, callable $in_view_port, callable $on_page, $auxiliary)
|
||||
{
|
||||
$this->onScreen = $on_screen;
|
||||
$this->inViewPort = $in_view_port;
|
||||
$this->onPage = $on_page;
|
||||
$this->auxiliary = $auxiliary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws UnsupportedOperationException
|
||||
* @return WebDriverPoint
|
||||
*/
|
||||
public function onScreen()
|
||||
{
|
||||
throw new UnsupportedOperationException(
|
||||
'onScreen is planned but not yet supported by Selenium'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WebDriverPoint
|
||||
*/
|
||||
public function inViewPort()
|
||||
{
|
||||
return call_user_func($this->inViewPort);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WebDriverPoint
|
||||
*/
|
||||
public function onPage()
|
||||
{
|
||||
return call_user_func($this->onPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The attached object id.
|
||||
*/
|
||||
public function getAuxiliary()
|
||||
{
|
||||
return $this->auxiliary;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverDoubleClickAction extends WebDriverMouseAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->mouse->doubleClick($this->getActionLocation());
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
class WebDriverKeyDownAction extends WebDriverSingleKeyAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->focusOnElement();
|
||||
$this->keyboard->pressKey($this->key);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
class WebDriverKeyUpAction extends WebDriverSingleKeyAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->focusOnElement();
|
||||
$this->keyboard->releaseKey($this->key);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\Internal\WebDriverLocatable;
|
||||
use Facebook\WebDriver\WebDriverKeyboard;
|
||||
use Facebook\WebDriver\WebDriverMouse;
|
||||
|
||||
/**
|
||||
* Base class for all keyboard-related actions.
|
||||
*/
|
||||
abstract class WebDriverKeysRelatedAction
|
||||
{
|
||||
/**
|
||||
* @var WebDriverKeyboard
|
||||
*/
|
||||
protected $keyboard;
|
||||
/**
|
||||
* @var WebDriverMouse
|
||||
*/
|
||||
protected $mouse;
|
||||
/**
|
||||
* @var WebDriverLocatable|null
|
||||
*/
|
||||
protected $locationProvider;
|
||||
|
||||
/**
|
||||
* @param WebDriverKeyboard $keyboard
|
||||
* @param WebDriverMouse $mouse
|
||||
* @param WebDriverLocatable $location_provider
|
||||
*/
|
||||
public function __construct(
|
||||
WebDriverKeyboard $keyboard,
|
||||
WebDriverMouse $mouse,
|
||||
WebDriverLocatable $location_provider = null
|
||||
) {
|
||||
$this->keyboard = $keyboard;
|
||||
$this->mouse = $mouse;
|
||||
$this->locationProvider = $location_provider;
|
||||
}
|
||||
|
||||
protected function focusOnElement()
|
||||
{
|
||||
if ($this->locationProvider) {
|
||||
$this->mouse->click($this->locationProvider->getCoordinates());
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\Internal\WebDriverLocatable;
|
||||
use Facebook\WebDriver\WebDriverMouse;
|
||||
|
||||
/**
|
||||
* Base class for all mouse-related actions.
|
||||
*/
|
||||
class WebDriverMouseAction
|
||||
{
|
||||
/**
|
||||
* @var WebDriverMouse
|
||||
*/
|
||||
protected $mouse;
|
||||
/**
|
||||
* @var WebDriverLocatable
|
||||
*/
|
||||
protected $locationProvider;
|
||||
|
||||
/**
|
||||
* @param WebDriverMouse $mouse
|
||||
* @param WebDriverLocatable|null $location_provider
|
||||
*/
|
||||
public function __construct(WebDriverMouse $mouse, WebDriverLocatable $location_provider = null)
|
||||
{
|
||||
$this->mouse = $mouse;
|
||||
$this->locationProvider = $location_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|WebDriverCoordinates
|
||||
*/
|
||||
protected function getActionLocation()
|
||||
{
|
||||
if ($this->locationProvider !== null) {
|
||||
return $this->locationProvider->getCoordinates();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function moveToLocation()
|
||||
{
|
||||
$this->mouse->mouseMove($this->locationProvider);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverMouseMoveAction extends WebDriverMouseAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->mouse->mouseMove($this->getActionLocation());
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\Internal\WebDriverLocatable;
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
use Facebook\WebDriver\WebDriverMouse;
|
||||
|
||||
class WebDriverMoveToOffsetAction extends WebDriverMouseAction implements WebDriverAction
|
||||
{
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $xOffset;
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $yOffset;
|
||||
|
||||
/**
|
||||
* @param WebDriverMouse $mouse
|
||||
* @param WebDriverLocatable|null $location_provider
|
||||
* @param int|null $x_offset
|
||||
* @param int|null $y_offset
|
||||
*/
|
||||
public function __construct(
|
||||
WebDriverMouse $mouse,
|
||||
WebDriverLocatable $location_provider = null,
|
||||
$x_offset = null,
|
||||
$y_offset = null
|
||||
) {
|
||||
parent::__construct($mouse, $location_provider);
|
||||
$this->xOffset = $x_offset;
|
||||
$this->yOffset = $y_offset;
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->mouse->mouseMove(
|
||||
$this->getActionLocation(),
|
||||
$this->xOffset,
|
||||
$this->yOffset
|
||||
);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\Internal\WebDriverLocatable;
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
use Facebook\WebDriver\WebDriverKeyboard;
|
||||
use Facebook\WebDriver\WebDriverMouse;
|
||||
|
||||
class WebDriverSendKeysAction extends WebDriverKeysRelatedAction implements WebDriverAction
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $keys = '';
|
||||
|
||||
/**
|
||||
* @param WebDriverKeyboard $keyboard
|
||||
* @param WebDriverMouse $mouse
|
||||
* @param WebDriverLocatable $location_provider
|
||||
* @param string $keys
|
||||
*/
|
||||
public function __construct(
|
||||
WebDriverKeyboard $keyboard,
|
||||
WebDriverMouse $mouse,
|
||||
WebDriverLocatable $location_provider = null,
|
||||
$keys = ''
|
||||
) {
|
||||
parent::__construct($keyboard, $mouse, $location_provider);
|
||||
$this->keys = $keys;
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->focusOnElement();
|
||||
$this->keyboard->sendKeys($this->keys);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Internal;
|
||||
|
||||
use Facebook\WebDriver\Internal\WebDriverLocatable;
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
use Facebook\WebDriver\WebDriverKeyboard;
|
||||
use Facebook\WebDriver\WebDriverKeys;
|
||||
use Facebook\WebDriver\WebDriverMouse;
|
||||
|
||||
abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction implements WebDriverAction
|
||||
{
|
||||
const MODIFIER_KEYS = [
|
||||
WebDriverKeys::SHIFT,
|
||||
WebDriverKeys::LEFT_SHIFT,
|
||||
WebDriverKeys::RIGHT_SHIFT,
|
||||
WebDriverKeys::CONTROL,
|
||||
WebDriverKeys::LEFT_CONTROL,
|
||||
WebDriverKeys::RIGHT_CONTROL,
|
||||
WebDriverKeys::ALT,
|
||||
WebDriverKeys::LEFT_ALT,
|
||||
WebDriverKeys::RIGHT_ALT,
|
||||
WebDriverKeys::META,
|
||||
WebDriverKeys::RIGHT_META,
|
||||
WebDriverKeys::COMMAND,
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @todo Remove default $key value in next major version (BC)
|
||||
*/
|
||||
public function __construct(
|
||||
WebDriverKeyboard $keyboard,
|
||||
WebDriverMouse $mouse,
|
||||
WebDriverLocatable $location_provider = null,
|
||||
$key = ''
|
||||
) {
|
||||
parent::__construct($keyboard, $mouse, $location_provider);
|
||||
|
||||
if (!in_array($key, self::MODIFIER_KEYS, true)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf(
|
||||
'keyDown / keyUp actions can only be used for modifier keys, but "%s" was given',
|
||||
$key
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->key = $key;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverDoubleTapAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->doubleTap($this->locationProvider);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverDownAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $x;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* @param WebDriverTouchScreen $touch_screen
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*/
|
||||
public function __construct(WebDriverTouchScreen $touch_screen, $x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
parent::__construct($touch_screen);
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->down($this->x, $this->y);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverFlickAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $x;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* @param WebDriverTouchScreen $touch_screen
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*/
|
||||
public function __construct(WebDriverTouchScreen $touch_screen, $x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
parent::__construct($touch_screen);
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->flick($this->x, $this->y);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
use Facebook\WebDriver\WebDriverElement;
|
||||
|
||||
class WebDriverFlickFromElementAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $x;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $y;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $speed;
|
||||
|
||||
/**
|
||||
* @param WebDriverTouchScreen $touch_screen
|
||||
* @param WebDriverElement $element
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @param int $speed
|
||||
*/
|
||||
public function __construct(
|
||||
WebDriverTouchScreen $touch_screen,
|
||||
WebDriverElement $element,
|
||||
$x,
|
||||
$y,
|
||||
$speed
|
||||
) {
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
$this->speed = $speed;
|
||||
parent::__construct($touch_screen, $element);
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->flickFromElement(
|
||||
$this->locationProvider,
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->speed
|
||||
);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverLongPressAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->longPress($this->locationProvider);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverMoveAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
private $x;
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* @param WebDriverTouchScreen $touch_screen
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*/
|
||||
public function __construct(WebDriverTouchScreen $touch_screen, $x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
parent::__construct($touch_screen);
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->move($this->x, $this->y);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverScrollAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
private $x;
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* @param WebDriverTouchScreen $touch_screen
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*/
|
||||
public function __construct(WebDriverTouchScreen $touch_screen, $x, $y)
|
||||
{
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
parent::__construct($touch_screen);
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->scroll($this->x, $this->y);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
use Facebook\WebDriver\WebDriverElement;
|
||||
|
||||
class WebDriverScrollFromElementAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
private $x;
|
||||
private $y;
|
||||
|
||||
/**
|
||||
* @param WebDriverTouchScreen $touch_screen
|
||||
* @param WebDriverElement $element
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*/
|
||||
public function __construct(
|
||||
WebDriverTouchScreen $touch_screen,
|
||||
WebDriverElement $element,
|
||||
$x,
|
||||
$y
|
||||
) {
|
||||
$this->x = $x;
|
||||
$this->y = $y;
|
||||
parent::__construct($touch_screen, $element);
|
||||
}
|
||||
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->scrollFromElement(
|
||||
$this->locationProvider,
|
||||
$this->x,
|
||||
$this->y
|
||||
);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Facebook\WebDriver\Interactions\Touch;
|
||||
|
||||
use Facebook\WebDriver\WebDriverAction;
|
||||
|
||||
class WebDriverTapAction extends WebDriverTouchAction implements WebDriverAction
|
||||
{
|
||||
public function perform()
|
||||
{
|
||||
$this->touchScreen->tap($this->locationProvider);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user