SlideShare a Scribd company logo
1 of 104
Download to read offline
Introduction aux tests de recette automatisés
Avec l'extension Drupal pour Behat
didier.boff@ows.fr
B2F @ drupal.org
https://github.com/B2F
http:///twitter.com/zenelse
Les joies du test
Quand mon collègue avance sans plan de test
http://lesjoiesdutest.tumblr.com
Plan
● Retour d'expérience
○ Campus France
○ Divers outils démodés
Plan
● Retour d'expérience
○ Campus France
○ Divers outils démodés
● Méthodologie
○ BDD, Gherkin
Plan
● Retour d'expérience
○ Campus France
○ Divers outils démodés
● Méthodologie
○ BDD, Gherkin
● Développement
○ Behat/Mink
○ MinkExtension (démo)
○ DrupalExtension (démo)
Retour d'expérience
www.campusfrance.org
● Migration Drupal 6 -> 7
Retour d'expérience
www.campusfrance.org
● Migration Drupal 6 -> 7
● 100 sites, domain access
● multilingues
Retour d'expérience
www.campusfrance.org
● Migration Drupal 6 -> 7
● 100 sites, domain access
● multilingues
Quels tests ?
Retour d'expérience
Selenium
API
● click
● type
● select
● addSelection
● submit
● ... http://release.seleniumhq.org/selenium-
core/
Retour d'expérience
Selenium
IDE
Retour d'expérience
?
Test automatisé
Selenium
IDE
Retour d'expérience
Selenium
IDE
?
Test automatisé
Multidomaine
Retour d'expérience
Selenium
IDE
?AJAX
Multidomaine
Test automatisé
Retour d'expérience
Selenium Server
http://docs.seleniumhq.org/download/
java -jar selenium-server-standalone-<version-number>.jar
http://selenium.googlecode.com/files/selenium-server-standalone-2.33.0.jar
Retour d'expérience
Selenium Server
+ PHPUnit
PHPUnit_Extensions_SeleniumTestCase
Retour d'expérience
Selenium Server
+ PHPUnit
https://github.com/B2F/ows-phpunit
class OWSeleniumTestCase extends
PHPUnit_Extensions_SeleniumTestCase {
public function __construct($name = NULL, array $data = array(),
$dataName = '') {
Retour d'expérience
Selenium Server
+ PHPUnit
+ IDE
Retour d'expérience
Selenium Server
+ PHPUnit
+ IDE
+
Selenium IDE: PHP Formatters
https://github.com/brokenthumbs/PHP-Formatter
Retour d'expérience
Selenium Server
+ PHPUnit
+ IDE
+
Selenium IDE: PHP Formatters
https://github.com/brokenthumbs/PHP-Formatter
https://github.com/B2F/PHP-Formatter
Les joies du test
Quand je fais un test un peu trop compliqué pour un truc
tout simple
http://lesjoiesdutest.tumblr.com
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple ?
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple
19 content types
Les joies du test
Quand je fais un test un peu trop
compliqué pour un truc tout simple
...
Méthodologie
● Behavior Driven Development (BDD)
Méthodologie
● Behavior Driven Development (BDD)
DrupalCon Portland 2013: BEHAT, BEHAVIORAL-
DRIVEN DEVELOPMENT AND SELENIUM IN DRUPAL
Ryan Weaver
https://portland2013.drupal.org
Méthodologie
● Gherkin
Méthodologie
● Gherkin
● Feature Suite de tests
Méthodologie
● Gherkin
● Feature
○ Scenario Test
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
Contexte
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
Contexte
Given I am on "/restaurants"
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
■ When
● And...
Évènements
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
■ When
● And...
Évènements
And I enter "Vietnam" for "pays"
And I enter "Bo Bun" for "plats"
And I enter "Paris 13" for "lieu"
Méthodologie
● Gherkin
● Feature
○ Scenario
■ Given
● And...
■ When
● And...
■ Then
● And...
Résultats
Then I should see the text "Pho Bida"
Opened Blackbox
● Cucumber
Gherkin + Ruby
Opened Blackbox
● Cucumber
=
Gherkin + Ruby
Opened Blackbox
● Cucumber
Gherkin + Ruby ?
Opened Blackbox
● Cucumber
Gherkin + PHP
Opened Blackbox
● Behat
http://behat.org/
=
Gherkin + PHP
Opened Blackbox
http://behat.org/
<?php
use BehatBehatContextBehatContext
class FeatureContext extends BehatContext
{
// /**
// * @Given /^I have done something with "([^"]*)"$/
// */
// public function iHaveDoneSomethingWith($argument)
// {
// doSomethingWith($argument);
// }
}
● Behat: ça fait quoi ?
Opened Blackbox
http://behat.org/
<?php
use BehatBehatContextBehatContext
class FeatureContext extends BehatContext
{
// /**
// * @Given /^I have done something with "([^"]*)"$/
// */
// public function iHaveDoneSomethingWith($argument)
// {
// doSomethingWith($argument);
// }
}
● Behat: ça fait quoi ?
Opened Blackbox
● Mink
Web acceptance testing
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$driver = new BehatMinkDriverZombieDriver();
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$driver = new BehatMinkDriverSahiDriver('firefox');
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$driver = new BehatMinkDriverGoutteDriver();
http://mink.behat.org/
Opened Blackbox
● Mink: drivers
$client = new SeleniumClient($host, $port);
$driver = new BehatMinkDriverSeleniumDriver(
'firefox', 'base_url', $client
);
http://mink.behat.org/
Opened Blackbox
● Mink: session
// init session:
$session = new BehatMinkSession($driver);
// start session:
$session->start();
http://mink.behat.org/
$session->visit('http://paris2013.drupalcamp.fr');
Opened Blackbox
● Mink: méthodes
$page = $session->getPage();
$element = $page->find('css', 'a#selector');
$element->getText();
http://mink.behat.org/
Opened Blackbox
● Mink: méthodes
$page = $session->getPage();
$element = $page->find('css', 'a#selector');
$element->getText();
http://mink.behat.org/
Développement
● En pratique
http://mink.behat.org/
Behat + Mink ?
Développement
● Mink extension
http://mink.behat.org/
=
Behat + Mink
Développement
● Mink extension
http://mink.behat.org/
STEPS
Développement
● Mink extension
http://mink.behat.org/
Given /^(?:|I )am on (?:|the )homepage$/
When /^(?:|I )go to (?:|the )homepage$/
Given /^(?:|I )am on "(?P<page>[^"]+)"$/
When /^(?:|I )go to "(?P<page>[^"]+)"$/
When /^(?:|I )reload the page$/
When /^(?:|I )move backward one page$/
When /^(?:|I )move forward one page$/
When /^(?:|I )press "(?P<button>(?:[^"]|")*)"$/
When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/
When /^(?:|I )fill in "(?P<field>(?:[^"]|")*)" with "(?P<value>(?:[^"]|")*)"$/
When /^(?:|I )fill in "(?P<field>(?:[^"]|")*)" with:$/
When /^(?:|I )fill in "(?P<value>(?:[^"]|")*)" for "(?P<field>(?:[^"]|")*)"$/
When /^(?:|I )fill in the following:$/
When /^(?:|I )select "(?P<option>(?:[^"]|")*)" from "(?P<select>(?:[^"]|")*)"$/
When /^(?:|I )additionally select "(?P<option>(?:[^"]|")*)" from "(?P<select>(?:[^"]|")*)"$/
...
bin/behat -dl
Développement
● Mink extension
http://mink.behat.org/
Presses button with specified id|name|title|alt|value.
@When /^(?:|I )press "(?P<button>(?:[^"]|")*)"$/
Clicks link with specified id|title|alt|text.
@When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/
Behat/MinkExtension/Context/MinkContext.php
Développement
Installation
http://docs.behat.org/#cookbook
Developing Web Applications with Behat and Mink
Développement
Installation
composer.json
{
"require": {
"behat/behat": "2.4.*@stable",
"behat/mink": "1.4.*@stable",
"behat/mink-extension": "*",
"behat/mink-goutte-driver": "*",
"behat/mink-selenium2-driver": "*"
},
"minimum-stability": "dev",
"config": {
"bin-dir": "bin/"
}
} http://docs.behat.org/cookbook/behat_and_mink.html
Développement
Installation
$ curl http://getcomposer.org/installer | php
$ php composer.phar install
http://docs.behat.org/cookbook/behat_and_mink.html
Développement
Installation
$ ls
bin composer.json composer.lock composer.phar vendor
http://docs.behat.org/cookbook/behat_and_mink.html
Développement
Installation
$ bin/behat --init
-> features/
Développement
Installation: suites de tests
features/{name}.feature
Feature: un exemple
Quelques steps pour illustrer une feature
Scenario: vérification qu'un lien est présent
Given I am at "/home"
When I click "Se connecter"
Then I should see "login"
Développement
Installation: customisation
$ bin/behat --init
-> features/bootstrap/FeatureContext.php
Développement
Installation: customisation
# features/bootstrap/FeatureContext.php
/**
* Features context.
*/
class FeatureContext extends BehatContext
{
...
Développement
Installation: customisation
# features/bootstrap/FeatureContext.php
/**
* Features context.
*/
class FeatureContext extends BehatContext
{
...
Développement
Installation: customisation
# features/bootstrap/FeatureContext.php
/**
* Features context.
*/
class FeatureContext extends MinkContext
{
...
Développement
Installation: subcontexts
# features/bootstrap/FeatureContext.php
use BehatMinkExtensionContextRawMinkContext;
use BehatMinkExtensionContextMinkContext;
class FeatureContext extends RawMinkContext
{
public function __construct(array $parameters)
{
$this->useContext('mink', new MinkContext);
}
}
http://extensions.behat.org/mink/
Développement
Installation: subcontexts
# features/bootstrap/FeatureContext.php
use BehatMinkExtensionContextRawMinkContext;
use BehatMinkExtensionContextMinkContext;
class FeatureContext extends RawMinkContext
{
public function __construct(array $parameters)
{
$this->useContext('mink', new MinkContext);
}
}
http://extensions.behat.org/mink/
Développement
● Mink steps
When will this be over ?
http://mink.behat.org/
Développement
● Mink steps
When I hover the element ?
/**
* @When /^I hover "([^"]*)"$/
*/
public function iHover($cssId)
{
http://mink.behat.org/
When will this be over ?
Développement
● Mink steps
/**
* @When /^I hover "([^"]*)"$/
*/
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
if (null === $element) {
throw new ElementNotFoundException($this->getSession(), 'element', 'css', $
}
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
__construct(Session session, string type, string selector, string locator)
And I hover "a[title='abcdefghi']" # FeatureContext::iHover()
Element matching css "a[title='abcdefghi']" not found.
throw new ElementNotFoundException
($this->getSession(), 'element', 'css', $cssId);
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
if (null === $element) {
throw new ElementNotFoundException($this->getSession(), 'element', 'css', $cssId
}
$element->mouseOver();
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps
public function iHover($cssId)
{
$page = $this->getSession()->getPage();
$element = $page->find('css', $cssId);
if (null === $element) {
throw new ElementNotFoundException($this->getSession(), 'element', 'css', $cssId
}
$element->mouseOver();
Attention: Selenium supporte le
mouseOver Javascript only :(
http://mink.behat.org/api/behat/mink/element/nodeelement.html
Développement
● Mink steps - AJAX
/**
* Waits some time or until JS condition turns true.
*
* @param integer $time time in milliseconds
* @param string $condition JS condition
*/
public function wait($time, $condition = 'false')
{
$this->driver->wait($time, $condition);
}
http://mink.behat.org/api/source/behat/mink/session.php.html
Développement
● Mink steps - AJAX
/**
* @When /^I wait (?P<timing>d+)sec$/
*/
public function iWaitNSec($timing) {
$this->getSession()->wait($timing*1000);
}
http://mink.behat.org/api/source/behat/mink/session.php.html
Développement
● Mink steps - AJAX
/**
* @When /^I wait (?P<timing>d+)sec$/
*/
public function iWaitNSec($timing) {
$this->getSession()->wait($timing*1000);
}
http://mink.behat.org/api/source/behat/mink/session.php.html
Développement
Démo
bin/behat features/demo.feature
Développement
Démo: colored output
bin/behat --ansi features/demo.feature
behat arguments: http://docs.behat.org/guides/6.cli.html
Développement
● OwsContext
https://github.com/B2F/OwsContext
public function iHover($cssId)
public function iWaitNsec($timing)
public function iClickTheElementMatching($selector)
Développement
● OwsContext
https://github.com/B2F/OwsContext
+ (experimental)
public function iWaitNSecForTheText($timing, $text)
public function iSwitchToTheIframeNamed($iframe)
public function iSwitchBackFromIframe()
Développement
Configuration
# behat.yml
default:
extensions:
BehatMinkExtensionExtension:
base_url: http://google.fr
goutte: ~
selenium2: ~
Développement
Configuration
● AJAX
@javascript
Scenario: vérification qu'un lien est présent
Given I am at "/home"
When I follow "my account"
Then I should see "my page title"
Développement
Configuration
● Profiles = overrides
# behat.yml
default:
...
custom:
extensions:
BehatMinkExtensionExtension:
base_url: http://another-url.com
Développement
Configuration
● Profiles
# bin/behat --profile=custom features/tests.feature
Développement
Configuration
● Filtres
# behat.yml
custom:
...
extensions:
...
filters:
tags: "@custom-filter"
Développement
Configuration
● Filtres
@javascript @custom-filter
Scenario: vérification qu'un lien est présent
Given I am at "/home"
When I hover "Se connecter"
Then I wait 1sec for the text "login"
Développement
● Drupal Extension
https://drupal.org/project/drupalextension
Développement
● Drupal Extension
/**
* Features context.
*/
class DrupalContext extends MinkContext implements DrupalAwareInterface {
private $drupal, $drupalParameters;
/**
* Basic auth user and password.
*/
public $basic_auth;
...
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: installation
# composer.json
{
"require": {
"drupal/drupal-extension": "*"
},
"minimum-stability": "dev",
"config": {
"bin-dir": "bin/"
}
}
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: installtion
$ curl http://getcomposer.org/installer | php
$ php composer.phar install
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: configuration
#behat.yml
default:
paths:
features: 'features'
extensions:
BehatMinkExtensionExtension:
goutte: ~
selenium2: ~
base_url: http://www.campusfrance.org/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: configuration
#behat.yml
default:
paths:
features: 'features'
extensions:
BehatMinkExtensionExtension:
goutte: ~
selenium2: ~
base_url: http://www.campusfrance.org/
DrupalDrupalExtensionExtension:
blackbox: ~
https://drupal.org/project/drupalextension
Développement
● Drupal Extension en pratique
bin/behat -dl => liste les steps
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: user steps
Given /^I am an anonymous user$/
Given /^I am not logged in$/
Given /^I am logged in as a user with the "(?P<role>[^"]*)" role$/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: configuration
#behat.yml
default:
paths:
features: 'features'
extensions:
...
DrupalDrupalExtensionExtension:
blackbox: ~
drush:
alias: myDrushAlias
https://drupal.org/project/drupalextension
Opened blackbox
● Drupal Extension: user steps
# @see Drupal/DrupalExtension/Context/DrupalContext.php
/**
* Helper function to login the current user.
*/
public function login() {
...
$this->getSession()->visit($this->locatePath('/user'));
$element = $this->getSession()->getPage();
$element->fillField($this->getDrupalText('username_field'), $this->user->name);
$element->fillField($this->getDrupalText('password_field'), $this->user->pass);
$submit = $element->findButton($this->getDrupalText('log_in'));
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: user steps
#behat.yml
DrupalDrupalExtensionExtension:
text:
log_out: "Sign out"
log_in: "Sign in"
password_field: "Enter your password"
username_field: "Nickname"
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: content steps
Given /^I am viewing (?:a|an) "(?P<type>[^"]*)" node with the title "(?P<title>[^"
Given /^I am viewing (?:a|an) "(?P<vocabulary>[^"]*)" term with the name "(?
P<name>[^"]*)"$/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: region steps
Then /^I should see the "(?P<heading>[^"]*)" heading in the "(?P<region>[^"]*)"(?:|reg
When /^I (?:follow|click) "(?P<link>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/
Then /^I should see the link "(?P<link>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/
Given /^I press "(?P<button>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: region steps
#behat.yml
DrupalDrupalExtensionExtension:
region_map:
My region: "#css-selector"
Content: "#main .region-content"
Right sidebar: "#sidebar-second"
https://drupal.org/project/drupalextension
Développement
● Drupal Extension: misc steps
Given /^the cache has been cleared$/
Given /^I run cron$/
https://drupal.org/project/drupalextension
Développement
Démo
Développement
Conclusion:
Utilisez BDD pour faire des tests de régressions.
Introduction aux tests de recette automatisés
Avec l'extension Drupal pour Behat
didier.boff@ows.fr
B2F @ drupal.org
https://github.com/B2F
http:///twitter.com/zenelse
Merci de votre attention

More Related Content

Similar to Drupal camp paris 2013: présentation de Behat, Mink et Drupal extension

Favorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp DirectorsFavorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp DirectorsJennifer Selke
 
Phpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and MinkPhpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and MinkRichard Tuin
 
Webinar - PuppetDB
Webinar - PuppetDBWebinar - PuppetDB
Webinar - PuppetDBOlinData
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceshipsSabin Marcu
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScriptT11 Sessions
 
Zero to hero - Geoff Webb
Zero to hero - Geoff WebbZero to hero - Geoff Webb
Zero to hero - Geoff WebbDevopsdays
 
Översättning av django-program
Översättning av django-programÖversättning av django-program
Översättning av django-programmikaelmoutakis
 
DrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual PanelDrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual PanelDoug Green
 
Practical Accessibility
Practical AccessibilityPractical Accessibility
Practical AccessibilityEli Cochran
 
Introduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPressIntroduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPressSeagyn Davis
 
Electronic Grading of Paper Assessments
Electronic Grading of Paper AssessmentsElectronic Grading of Paper Assessments
Electronic Grading of Paper AssessmentsMatthew Leingang
 
JLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App DevelopmentJLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App DevelopmentJLP Community
 
Groovy And Grails Introduction
Groovy And Grails IntroductionGroovy And Grails Introduction
Groovy And Grails IntroductionEric Weimer
 
BDD / cucumber /Capybara
BDD / cucumber /CapybaraBDD / cucumber /Capybara
BDD / cucumber /CapybaraShraddhaSF
 
Drupal site translation and translation testing
Drupal site translation and translation testingDrupal site translation and translation testing
Drupal site translation and translation testingjames_andres
 

Similar to Drupal camp paris 2013: présentation de Behat, Mink et Drupal extension (20)

Favorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp DirectorsFavorite Sites And iOS Applications Of Productive Camp Directors
Favorite Sites And iOS Applications Of Productive Camp Directors
 
Phpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and MinkPhpday - Automated acceptance testing with Behat and Mink
Phpday - Automated acceptance testing with Behat and Mink
 
Webinar - PuppetDB
Webinar - PuppetDBWebinar - PuppetDB
Webinar - PuppetDB
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceships
 
Devops
DevopsDevops
Devops
 
Code Management
Code ManagementCode Management
Code Management
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScript
 
Zero to hero - Geoff Webb
Zero to hero - Geoff WebbZero to hero - Geoff Webb
Zero to hero - Geoff Webb
 
Översättning av django-program
Översättning av django-programÖversättning av django-program
Översättning av django-program
 
DrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual PanelDrupalCon Paris Muiltilingual Panel
DrupalCon Paris Muiltilingual Panel
 
Practical Accessibility
Practical AccessibilityPractical Accessibility
Practical Accessibility
 
2013 10-25 dev-opsdays
2013 10-25 dev-opsdays2013 10-25 dev-opsdays
2013 10-25 dev-opsdays
 
13 Ddply
13 Ddply13 Ddply
13 Ddply
 
Introduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPressIntroduction to Continous Integration with WordPress
Introduction to Continous Integration with WordPress
 
Electronic Grading of Paper Assessments
Electronic Grading of Paper AssessmentsElectronic Grading of Paper Assessments
Electronic Grading of Paper Assessments
 
JLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App DevelopmentJLPDevs - Optimization Tooling for Modern Web App Development
JLPDevs - Optimization Tooling for Modern Web App Development
 
Introduction to Jifty
Introduction to JiftyIntroduction to Jifty
Introduction to Jifty
 
Groovy And Grails Introduction
Groovy And Grails IntroductionGroovy And Grails Introduction
Groovy And Grails Introduction
 
BDD / cucumber /Capybara
BDD / cucumber /CapybaraBDD / cucumber /Capybara
BDD / cucumber /Capybara
 
Drupal site translation and translation testing
Drupal site translation and translation testingDrupal site translation and translation testing
Drupal site translation and translation testing
 

Recently uploaded

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 

Recently uploaded (20)

Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 

Drupal camp paris 2013: présentation de Behat, Mink et Drupal extension