Setting Up Selenium Tests for 1C-Bitrix
Manual regression testing after every release is expensive. A broken checkout form, a catalog filter that fails on the third page, a cart that loses items after login — these scenarios can be caught by Selenium before a customer encounters them. For 1C-Bitrix sites where business logic is spread across PHP components and JavaScript, Selenium is the most appropriate tool: it tests a real browser, not mocks.
Setting Up Selenium Tests for 1C-Bitrix
Selenium Infrastructure for Bitrix
Selenium WebDriver with Java or Python is the classic stack. For PHP projects, PHP wrappers are preferable: php-webdriver/webdriver (Facebook PHP WebDriver) or Codeception with the WebDriver module.
Minimal infrastructure:
Tests (PHP/Python) → Selenium WebDriver → ChromeDriver/GeckoDriver → Browser → 1C-Bitrix site
For CI/CD — Selenium Grid or Selenium Standalone in Docker:
# docker-compose.selenium.yml
services:
selenium-chrome:
image: selenium/standalone-chrome:latest
ports:
- "4444:4444"
environment:
- SE_NODE_MAX_SESSIONS=3
shm_size: 2g
Configuration for Testing the Bitrix Environment
// tests/selenium/SeleniumTestCase.php
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverExpectedCondition;
abstract class BitrixSeleniumTest extends PHPUnit\Framework\TestCase
{
protected RemoteWebDriver $driver;
protected string $baseUrl = 'https://test.site.ru';
protected function setUp(): void
{
$caps = DesiredCapabilities::chrome();
$caps->setCapability('goog:chromeOptions', [
'args' => ['--headless', '--no-sandbox', '--disable-dev-shm-usage'],
]);
$this->driver = RemoteWebDriver::create(
'http://localhost:4444/wd/hub',
$caps,
30000, // connection timeout
30000 // request timeout
);
$this->driver->manage()->window()->setSize(
new \Facebook\WebDriver\WebDriverDimension(1280, 900)
);
}
protected function tearDown(): void
{
$this->driver->quit();
}
protected function waitForElement(string $selector, int $seconds = 10): \Facebook\WebDriver\WebDriverElement
{
return $this->driver->wait($seconds)->until(
WebDriverExpectedCondition::visibilityOfElementLocated(
WebDriverBy::cssSelector($selector)
)
);
}
protected function loginAsAdmin(): void
{
$this->driver->get($this->baseUrl . '/bitrix/admin/');
$this->driver->findElement(WebDriverBy::name('USER_LOGIN'))->sendKeys('admin');
$this->driver->findElement(WebDriverBy::name('USER_PASSWORD'))->sendKeys(getenv('BITRIX_ADMIN_PASS'));
$this->driver->findElement(WebDriverBy::cssSelector('[type=submit]'))->click();
}
}
Testing Critical User Scenarios
// tests/selenium/CheckoutFlowTest.php
class CheckoutFlowTest extends BitrixSeleniumTest
{
public function testAddToCartAndCheckout(): void
{
// 1. Open product card
$this->driver->get($this->baseUrl . '/catalog/tools/drills/bosch-gsh/');
// 2. Wait for button to load and click it
$addBtn = $this->waitForElement('[data-action="add-to-cart"]');
$addBtn->click();
// 3. Wait for cart counter to update
$counter = $this->waitForElement('.cart-counter');
$this->assertSame('1', $counter->getText());
// 4. Navigate to cart
$this->driver->get($this->baseUrl . '/cart/');
// 5. Verify product is in cart
$cartItem = $this->waitForElement('.cart-item');
$this->assertStringContainsString('Bosch GSH', $cartItem->getText());
// 6. Click checkout
$this->driver->findElement(
WebDriverBy::cssSelector('.checkout-btn')
)->click();
// 7. Wait for checkout page
$this->waitForElement('#checkout-form');
$this->assertStringContainsString('/order/', $this->driver->getCurrentURL());
}
}
Testing the Smart Catalog Filter
class CatalogFilterTest extends BitrixSeleniumTest
{
public function testFilterByBrandUpdatesListing(): void
{
$this->driver->get($this->baseUrl . '/catalog/tools/');
// Wait for filter to load
$this->waitForElement('.catalog-filter');
// Click the "Bosch" brand filter checkbox
$brandCheckbox = $this->driver->findElement(
WebDriverBy::cssSelector('[data-filter="brand"][value="bosch"]')
);
$brandCheckbox->click();
// Wait for AJAX product list update
$this->driver->wait(10)->until(
WebDriverExpectedCondition::invisibilityOfElementLocated(
WebDriverBy::cssSelector('.catalog-loading')
)
);
// Verify URL has changed (SEO-friendly filter URL)
$this->assertStringContainsString('brand=bosch', $this->driver->getCurrentURL());
// Verify all cards contain "Bosch"
$cards = $this->driver->findElements(
WebDriverBy::cssSelector('.product-card .product-brand')
);
foreach ($cards as $card) {
$this->assertSame('Bosch', $card->getText());
}
}
}
Timelines
| Task | Timeline |
|---|---|
| Set up Selenium Grid in Docker, base configuration | 4–8 hours |
| Tests for critical scenarios (cart, filter, login) | 1–2 days |
| Integration into CI/CD pipeline | 4–8 hours |







