Skip to content

Commit c08049b

Browse files
committed
Issue #2947517 by Lendude, jibran, alexpott, larowlan: Selenium driver: API to get remote file paths
(cherry picked from commit 2c4ca06)
1 parent 2ea175e commit c08049b

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

tests/Drupal/FunctionalJavascriptTests/DrupalSelenium2Driver.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Drupal\FunctionalJavascriptTests;
44

55
use Behat\Mink\Driver\Selenium2Driver;
6+
use Behat\Mink\Exception\DriverException;
7+
use WebDriver\Exception\UnknownError;
68
use WebDriver\ServiceFactory;
79

810
/**
@@ -41,4 +43,69 @@ public function setCookie($name, $value = NULL) {
4143
$this->getWebDriverSession()->setCookie($cookieArray);
4244
}
4345

46+
/**
47+
* Uploads a file to the Selenium instance and returns the remote path.
48+
*
49+
* \Behat\Mink\Driver\Selenium2Driver::uploadFile() is a private method so
50+
* that can't be used inside a test, but we need the remote path that is
51+
* generated when uploading to make sure the file reference exists on the
52+
* container running selenium.
53+
*
54+
* @param string $path
55+
* The path to the file to upload.
56+
*
57+
* @return string
58+
* The remote path.
59+
*
60+
* @throws \Behat\Mink\Exception\DriverException
61+
* When PHP is compiled without zip support, or the file doesn't exist.
62+
* @throws \WebDriver\Exception\UnknownError
63+
* When an unknown error occurred during file upload.
64+
* @throws \Exception
65+
* When a known error occurred during file upload.
66+
*/
67+
public function uploadFileAndGetRemoteFilePath($path) {
68+
if (!is_file($path)) {
69+
throw new DriverException('File does not exist locally and cannot be uploaded to the remote instance.');
70+
}
71+
72+
if (!class_exists('ZipArchive')) {
73+
throw new DriverException('Could not compress file, PHP is compiled without zip support.');
74+
}
75+
76+
// Selenium only accepts uploads that are compressed as a Zip archive.
77+
$tempFilename = tempnam('', 'WebDriverZip');
78+
79+
$archive = new \ZipArchive();
80+
$result = $archive->open($tempFilename, \ZipArchive::CREATE);
81+
if (!$result) {
82+
throw new DriverException('Zip archive could not be created. Error ' . $result);
83+
}
84+
$result = $archive->addFile($path, basename($path));
85+
if (!$result) {
86+
throw new DriverException('File could not be added to zip archive.');
87+
}
88+
$result = $archive->close();
89+
if (!$result) {
90+
throw new DriverException('Zip archive could not be closed.');
91+
}
92+
93+
try {
94+
$remotePath = $this->getWebDriverSession()->file(['file' => base64_encode(file_get_contents($tempFilename))]);
95+
96+
// If no path is returned the file upload failed silently.
97+
if (empty($remotePath)) {
98+
throw new UnknownError();
99+
}
100+
}
101+
catch (\Exception $e) {
102+
throw $e;
103+
}
104+
finally {
105+
unlink($tempFilename);
106+
}
107+
108+
return $remotePath;
109+
}
110+
44111
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace Drupal\FunctionalJavascriptTests\Tests;
4+
5+
use Drupal\entity_test\Entity\EntityTest;
6+
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
7+
use Drupal\Tests\file\Functional\FileFieldCreationTrait;
8+
use Drupal\Tests\TestFileCreationTrait;
9+
10+
/**
11+
* Tests the DrupalSelenium2Driver methods.
12+
*
13+
* @coversDefaultClass \Drupal\FunctionalJavascriptTests\DrupalSelenium2Driver
14+
* @group javascript
15+
*/
16+
class DrupalSelenium2DriverTest extends WebDriverTestBase {
17+
18+
use TestFileCreationTrait;
19+
use FileFieldCreationTrait;
20+
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
protected static $modules = ['file', 'field_ui', 'entity_test'];
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
protected function setUp() {
30+
parent::setUp();
31+
$storage_settings = ['cardinality' => 3];
32+
$this->createFileField('field_file', 'entity_test', 'entity_test', $storage_settings);
33+
$this->drupalLogin($this->drupalCreateUser([
34+
'administer entity_test content',
35+
'access content',
36+
]));
37+
}
38+
39+
/**
40+
* Tests uploading remote files.
41+
*/
42+
public function testGetRemoteFilePath() {
43+
$web_driver = $this->getSession()->getDriver();
44+
$file_system = \Drupal::service('file_system');
45+
$entity = EntityTest::create();
46+
$entity->save();
47+
48+
$files = array_slice($this->getTestFiles('text'), 0, 3);
49+
$real_paths = [];
50+
foreach ($files as $file) {
51+
$real_paths[] = $file_system->realpath($file->uri);
52+
}
53+
$remote_paths = [];
54+
foreach ($real_paths as $path) {
55+
$remote_paths[] = $web_driver->uploadFileAndGetRemoteFilePath($path);
56+
}
57+
58+
// Tests that uploading multiple remote files works with remote path.
59+
$this->drupalGet($entity->toUrl('edit-form'));
60+
$multiple_field = $this->xpath('//input[@multiple]')[0];
61+
$multiple_field->setValue(implode("\n", $remote_paths));
62+
$this->assertSession()->assertWaitOnAjaxRequest();
63+
$this->getSession()->getPage()->findButton('Save')->click();
64+
$entity = EntityTest::load($entity->id());
65+
$this->assertCount(3, $entity->field_file);
66+
}
67+
68+
}

0 commit comments

Comments
 (0)