Logo
  • A propos
  • Blog
  • Services
  • Media
  • Contact
Contactez-nous !
Logo

Accueil

Blog

Newsletters

Podcasts

Vidéos

Qui suis-je ?

Shift Op Solutions

Mentorat

Formations

Etat des Lieux

Contact

Copyright © Jean-François Fresi 2024 - Site créé en nocode.

LinkedInYouTubeSpotifyRSS

23 ans après le MIT, l’automatisation visuelle n’a plus besoin d’être commerciale

Date publication
Apr 22, 2026

23 ans après le MIT, l’automatisation visuelle n’a plus besoin d’être commerciale

Cet article est publié sans sponsoring, sans partenariat commercial et sans intérêt financier extérieur. Il s’adresse aux équipes qui évaluent une solution d’automatisation visuelle en 2026 et veulent connaître toutes les options disponibles, y compris celles qui ne paient pas pour apparaître dans les médias spécialisés.

Cet article est rédigé par Julien Mer.

image

1 - Les défis du test d’applications critiques

Les applications packagées, les progiciels métier, les systèmes embarqués, les interfaces distantes — autant d’environnements qui doivent être testés régulièrement pour s’assurer qu’aucune régression fonctionnelle ne s’introduit. Ces applications présentent des contraintes que les outils traditionnels peinent à couvrir.

Le cœur éditeur et la customisation spécifique

La majorité des progiciels permettent de développer ses propres fonctionnalités par-dessus le socle éditeur. Deux rythmes de release cohabitent : celui de l’éditeur sur le cœur, celui de l’entreprise sur la customisation. Les méthodologies de développement peuvent différer, ce qui multiplie les surfaces de test et les points de régression potentiels.

L’instabilité des identifiants techniques

Les éditeurs modifient fréquemment la structure interne du code. Sur une application web, cela se traduit par des changements d’identifiants HTML entre deux versions. Une stratégie d’automatisation fondée sur la couche objet expose à des coûts de maintenance importants à chaque montée de version, puisque l’ensemble des scripts devra être revu.

Le mur du client lourd

Beaucoup d’applications métier fonctionnent encore sur une base de client lourd. L’automatisation y est complexe : les éléments de code exploitables pour piloter l’interface sont difficiles à identifier, parfois inaccessibles. Les outils conçus pour le web ou le mobile moderne sont inopérants.

Les parcours cross-plateformes

Tester un processus métier réel implique souvent plusieurs interfaces : une application web et un client lourd, un front-end et un back-office, une interface bureau et une application mobile. Cette hétérogénéité allonge le temps de rédaction des scripts, parfois jusqu’à rendre l’automatisation impossible avec une approche traditionnelle.

Les environnements distants et embarqués

Caisses enregistreuses pilotées par VNC, kiosks en datacenter, tablettes Android en production sur le terrain, serveurs accessibles uniquement via un bastion SSH — ces contextes sortent du périmètre de la plupart des frameworks de test modernes.

2 – La réponse OculiX : voir, comprendre, agir

OculiX est la continuation open source de SikuliX — projet de recherche démarré au MIT CSAIL dès 2003 dans le User Interface Design Group du Professeur Rob Miller, formalisé publiquement au papier UIST 2009 par Tom Yeh et Tsung-Hsiang Chang, puis repris et maintenu en production pendant 13+ ans par Raimund Hocke, avant d’être transmis à l’organisation oculix-org en mars 2026.

L’approche est simple et puissante : OculiX regarde l’écran comme un humain. Aucune dépendance au DOM, à une API d’accessibilité ou à un driver. L’outil fonctionne sur tout ce qui est visible.

Le moteur de reconnaissance visuelle

OculiX s’appuie sur OpenCV 4.10 pour effectuer du template matching pixel-par-pixel. Tout élément à l’écran — bouton, icône, logo, zone de saisie, graphique, photo — peut être capturé et retrouvé dynamiquement lors de l’exécution d’un script. Le moteur supporte les Pattern avec similarity configurable, les masks, les target offsets. Les API find, findAll, wait, waitVanish, exists, click, doubleClick, rightClick, type, paste, dragDrop, wheel et hover sont intégralement préservées depuis SikuliX pour une compatibilité totale avec l’existant.

L’OCR double moteur

Lorsque les éléments à détecter sont du texte, OculiX embarque deux moteurs OCR complémentaires.

Tesseract est bundlé directement dans le jar via tess4j. Disponible immédiatement sans installation, il couvre la majorité des besoins courants avec une bonne performance.

PaddleOCR est déployé en local via un microservice Python léger. Son réseau neuronal offre une précision très supérieure sur les interfaces complexes : polices industrielles, affichages LCD, écrans de caisse, interfaces anciennes en basse résolution, langues non latines.

Le basculement entre les deux moteurs se fait via une interface OCREngine unifiée. Le testeur choisit son trade-off précision-performance sans toucher à son code métier.

Dans la plupart des applications packagées, le texte porte le métier. Si une interface change visuellement mais que les libellés restent identiques, les scripts continuent de fonctionner sans maintenance.

Le Modern Recorder, no-code par défaut

L’IDE OculiX intègre un enregistreur guidé pas-à-pas. Là où les recorders classiques enregistrent tout en aveugle puis génèrent un pavé de code, OculiX propose une expérience transparente : l’utilisateur clique sur un bouton d’action (Click, Type, Wait, Swipe…), capture une zone, lui donne un nom, et voit la ligne de code correspondante s’ajouter en preview.

Chaque action est auditable avant insertion. Les images déjà capturées peuvent être réutilisées pour éviter les doublons. Un validateur de pattern détecte à la volée les captures ambiguës (plusieurs correspondances à l’écran), dépendantes de la couleur (risque de casse en dark mode) ou insuffisamment détaillées.

Les modales avancées couvrent les cas complexes :

  • Key Combo avec checkboxes Ctrl/Alt/Shift/Meta et dropdown de touches spéciales
  • Wheel avec crosshair interactif pour placer l’offset au pixel près
  • Swipe avec D-pad, slider de distance, point de départ positionnable, désactivation automatique des directions qui sortiraient du cadre
  • DragDrop avec trois sources au choix pour chaque image : capture écran, fichier local, bibliothèque de session

À l’insertion, le code est placé dans l’éditeur, les images copiées dans le bundle .sikuli du script, et le tout est prêt à s’exécuter.

L’API Java, cœur du produit

OculiX est avant tout une API Java publiée sur Maven Central sous l’identifiant io.github.oculix-org:oculixapi:3.0.1. Un développeur Java, Kotlin, Scala, Groovy ou Clojure l’ajoute comme n’importe quelle dépendance Maven ou Gradle dans son projet et l’utilise directement. Pas d’IDE à installer, pas de Jython dans la boucle, pas de script .py, pas de serveur à démarrer. Une lib Java standard, point.

Le minimum vital — trouver un bouton à l’écran, cliquer dessus, saisir du texte, attendre un écran :

import org.sikuli.script.Screen;
import org.sikuli.script.Pattern;
import org.sikuli.script.FindFailed;

public class HelloOculix {
    public static void main(String[] args) throws FindFailed {
        Screen s = new Screen();
        s.click(new Pattern("login_button.png").similar(0.85f));
        s.type("admin");
        s.wait(new Pattern("dashboard.png"), 10);
    }
}

Quatre lignes métier, trois imports, et l’automatisation visuelle fonctionne. Une Screen, un Pattern, et l’API répond. Ce code peut tenir dans une classe main autonome, un test JUnit, un test Spock en Groovy, une étape de pipeline Jenkins, un job Gradle — n’importe quel contexte JVM l’accepte. L’OCR suit la même logique. Pour lire ou chercher du texte à l’écran, aucun setup supplémentaire :

Le mélange image + texte est transparent : s.find("bouton.png") retourne une Region sur laquelle .text() extrait le texte via OCR, et s.click("Valider") cherche directement une chaîne de caractères à l’écran sans passer par une capture d’image préalable.

Les packages de l’API

Les packages racines de l’API OculiX ont été conservés tels quels depuis SikuliX historique. C’est un choix de continuité délibéré, pas un oubli de refactoring : des milliers de projets, scripts et dépendances dans le monde réel pointent sur org.sikuli.*, et un rebrand org.oculix.* aurait cassé tout cet écosystème du jour au lendemain. Un développeur qui connaissait SikuliX retrouve ses imports à l’identique ; un nouveau venu découvre un package standard et cohérent. Personne ne perd en route.

Package
Contenu
org.sikuli.script
Cœur — Screen, Region, Pattern, Match, Image, App, Location, Mouse, Keys, Key, Finder, OCR, FindFailed
org.sikuli.basics
Debug, Settings, HotkeyManager
org.sikuli.support
Helpers, Commons, RunTime
org.sikuli.vnc
VNCScreen, VNCRobot, VNCClient, VNCFrameBuffer
org.sikuli.android
ADBScreen, ADBClient, ADBDevice, ADBRobot
com.sikulix.util
SSHTunnel
com.sikulix.ocr
OCREngine (interface), PaddleOCREngine, PaddleOCRClient, TesseractEngine

Les options au-dessus de l’API : IDE, Modern Recorder, scripting hérité

Au-dessus de cette API, OculiX fournit plusieurs outils d’emploi pour des publics différents, qui sont tous des consommateurs de l’API au même titre qu’un projet Java tiers.

L’IDE OculiX est un environnement graphique qui embarque Jython 2.7, un interpréteur Python écrit en Java et tournant à l’intérieur de la JVM. Il permet d’écrire des scripts en Python 2 avec accès transparent à l’API Java. C’est le mode d’entrée historique de SikuliX, maintenu pour garantir la compatibilité totale avec la base existante. Python 2 étant en fin de vie depuis 2020, un passage à un runtime Python 3 (GraalPy pressenti pour rester in-process dans la JVM, sans exiger d’installation CPython côté utilisateur) est planifié dans une prochaine release. Les scripts Jython existants resteront compatibles via une couche de portage.

Le Modern Recorder de l’IDE permet de capturer visuellement une séquence d’actions et d’en générer le code correspondant. Il cible aujourd’hui Jython par héritage de SikuliX, avec le Java natif en premier chantier d’extension pour produire directement des classes de test intégrables dans un projet Maven ou Gradle.

Pour les équipes qui préfèrent d’autres langages JVM, JRuby 9.2, PowerShell, AppleScript et Robot Framework (via SikuliLibrary) peuvent également appeler l’API. Et pour les testeurs non-développeurs, le vocabulaire OculiX — click, type, find, wait, dragDrop, swipe — reste immédiatement lisible, quel que soit le langage hôte.

Une plateforme JVM ouverte, sans pont ni wrapper

OculiX n’est pas un silo. Son API Java s’intègre nativement à tout l’écosystème Maven Central, comme n’importe quelle autre dépendance. Une suite de tests peut importer OculiX à côté de Selenium WebDriver, Rest Assured, Apache POI, JDBC, PDFBox, Jackson, Jsoup, WireMock ou JUnit sans la moindre configuration spéciale. Deux lignes dans le pom.xml, deux sets d’imports dans la classe de test, un seul flux d’exécution.

Un exemple concret — Selenium pilote le DOM, OculiX prend le relais sur ce que Selenium ne peut pas tester :

Aucun pont à construire, aucun wrapper à écrire, aucun chargement dynamique à orchestrer. C’est juste du Java standard. Le même code tient dans une classe JUnit, un test Spock en Groovy, ou un pipeline Jenkins déclaratif, sans modification autre que syntaxique.

Ce point est approfondi en section 5, avec un exemple complet à huit stacks techniques combinées et l’intégration à un Selenium Grid existant.

Le Modern Recorder, export multi-langage universel

Le Modern Recorder génère aujourd’hui du code Jython directement exécutable dans l’IDE, par héritage de SikuliX. Sa génération de code est construite sur une interface ICodeGenerator pensée pour être étendue à tout langage capable d’invoquer le jar oculixapi. Le premier chantier d’extension de cette roadmap est l’export Java natif, afin que le Recorder produise directement des classes de test intégrables dans un projet Maven ou Gradle.

La roadmap prévoit l’export du code enregistré dans tous les langages suivants :

  • Python 3 — via GraalPy (in-process JVM) ou CPython avec py4j / JPype
  • Java — export natif compatible Maven / Gradle
  • Kotlin, Scala, Groovy — tout l’écosystème JVM
  • JavaScript / TypeScript — via GraalJS en in-process, ou Node.js bridge
  • Ruby — via JRuby
  • C# / .NET — via IKVM.NET ou JNBridge
  • Go — via JNI wrapper
  • Rust — via JNI bindings
  • Swift et Objective-C — bindings natifs macOS via JNI
  • Perl, Tcl, Lua — via leurs passerelles JVM respectives
  • PowerShell et Bash/Shell — en sous-processus appelant le jar
  • AppleScript, VBScript — pour les scénarios scriptés OS natifs
  • R — pour les workflows scientifiques
  • Robot Framework, Gherkin BDD — pour les suites comportementales

Un utilisateur enregistre son scénario une fois avec le Modern Recorder. Au moment de l’insertion, il choisit son langage cible dans un dropdown. Le code généré est idiomatique du langage choisi, prêt à être collé dans son projet. Un commentaire d’en-tête rappelle comment ajouter le jar oculixapi au classpath si le langage cible n’est pas hébergé dans la JVM.

Cette feuille de route fait du Modern Recorder un véritable pont universel entre le no-code (clics guidés dans l’IDE) et le pro-code (n’importe quel stack moderne). Un testeur QA enregistre un scénario sans écrire une ligne ; un développeur récupère le même scénario en Kotlin ou en C# pour l’intégrer dans sa suite de tests existante. Un automaticien RPA exporte le même parcours en PowerShell pour le lancer depuis un ordonnanceur Windows. Une équipe Ruby teste ses applications via les mêmes captures d’écran que l’équipe Java.

La seule condition technique pour ajouter un nouveau langage au catalogue d’export est qu’il puisse invoquer l’API Java d’OculiX. Ce qui couvre, en 2026, à peu près tout ce qui tourne sur un ordinateur.

L’absence de serveur : un jar, rien d’autre

OculiX tient dans un seul jar, d’environ 150 Mo. Java 17 ou supérieur, double-clic, l’IDE démarre.

Pas de processus serveur HTTP à lancer en parallèle. Pas de driver à maintenir synchronisé avec les versions des navigateurs ou du système d’exploitation. Pas d’agent à déployer sur les machines à tester. Pas de port spécifique à ouvrir. Pas de service système à démarrer au boot. Pas de runtime externe à installer à côté. Pas de licence à renouveler.

Tout est embarqué dans le jar :

  • Le moteur visuel OpenCV 4.10
  • Tesseract pour l’OCR de base
  • JSch pour les tunnels SSH
  • Le client VNC complet avec encodage ZRLE
  • La stack ADB pour Android
  • Les runners Jython, JRuby, Java, PowerShell, AppleScript
  • Le Modern Recorder et tout l’IDE graphique

Le seul composant externe optionnel est le microservice paddleocr-server, utile lorsque la précision neuronale est requise. Il reste local, indépendant, et Tesseract embarqué suffit pour la majorité des cas.

Concrètement, pour un responsable QA ou un admin système :

  • Pas d’admin système à convaincre d’ouvrir un port
  • Pas de serveur à sauvegarder, superviser ou redémarrer
  • Pas de montée de version d’agent à orchestrer sur un parc
  • Pas de désynchronisation entre client et serveur à gérer
  • Pas de licence à renouveler
  • Pas de cloud dans la boucle

Un jar, une JVM, un écran. L’outil se comporte exactement comme un utilisateur humain qui serait assis devant la machine.

Le contrôle à distance natif

Ce modèle « tout-en-un » prend toute sa valeur lorsqu’il est combiné au support VNC natif d’OculiX. Là où la plupart des outils se limitent à la machine locale ou imposent d’installer un agent sur chaque cible, OculiX n’exige rien sur la machine à tester.

VNC intégré : les classes VNCScreen, VNCRobot, VNCClient, VNCFrameBuffer et VNCClipboard permettent de contrôler n’importe quelle machine exposant un serveur VNC. L’encodage ZRLE est supporté, le mapping clavier XKeySym couvre près de 2 000 touches internationales. L’API est identique à celle de Screen : un script local fonctionne tel quel sur un écran distant.

La majorité des serveurs Linux, machines virtuelles, postes virtualisés (Citrix, VDI), terminaux industriels embarqués, caisses retail et bornes libre-service exposent déjà un serveur VNC. OculiX s’y connecte depuis n’importe où et voit l’écran exactement comme un opérateur humain connecté en VNC. Aucun agent à installer sur la cible, aucun utilitaire à pousser via SCP, aucune porte d’entrée à ouvrir autre que VNC — et éventuellement SSH pour le tunnel. La machine distante peut être en air-gapped derrière un bastion, en datacenter sans accès direct, ou un kiosk embarqué en production depuis quinze ans : OculiX l’automatise depuis un poste de pilotage standard sans rien modifier sur la cible.

Pour les équipes qui gèrent des parcs de machines distantes — flottes retail, bornes libre-service, terminaux industriels, laboratoires pharma, serveurs bancaires, installations sensibles — c’est une capacité différenciante : pas d’installation sur les cibles, pas d’agent à maintenir, pas de désynchronisation à craindre. Un jar sur le poste de pilotage, une adresse IP, un tunnel SSH optionnel, et l’automatisation fonctionne.

Un exemple Java concret - piloter une caisse retail distante sur le port VNC standard :

L’API VNCScreen est strictement identique à Screen : toutes les méthodes (click, type, find, wait, drag, etc.) fonctionnent de la même manière. Un script écrit pour la machine locale se transforme en script de pilotage distant en changeant uniquement la ligne d’instanciation. Pour une cible derrière un bastion SSH, la classe SSHTunnel gère le forwarding sans outil externe :

Un try-with-resources, un tunnel, une VNCScreen, et l’automatisation traverse le bastion sans sshpass, sans WSL, sans script shell externe. C’est un pattern directement applicable dans n’importe quel test d’intégration Java qui cible une machine dans un réseau privé ou une DMZ.

SSH intégré : JSch est embarqué directement dans le jar. La classe SSHTunnel permet d’ouvrir un tunnel VNC-over-SSH en quelques lignes, sans sshpass, sans WSL, sans outil externe. Authentification par mot de passe ou par clés, configuration fine des ciphers, compatibilité avec les serveurs anciens.

Android ADB natif : ADBClient, ADBDevice, ADBRobot, ADBScreen couvrent Android 12 et versions supérieures, en USB comme en WiFi. Pas d’Appium à installer, pas de serveur intermédiaire à lancer. Un téléphone branché suffit pour commencer à automatiser.

Cette combinaison permet des scénarios inaccessibles aux frameworks traditionnels : tester des caisses enregistreuses en datacenter via un bastion SSH qui forwarde un port VNC, piloter en parallèle une flotte de tablettes Android sur le terrain, automatiser un kiosk embarqué sans accès physique à la machine.

Le déploiement local, souverain, auditable

Tout tourne en local. Aucun appel cloud, aucune télémétrie, aucune donnée qui quitte la machine de l’utilisateur. En 2026, c’est presque devenu une feature exotique. Le code source est ouvert sous licence MIT et auditable dans son intégralité. Ces propriétés sont des prérequis pour les environnements contraints : air-gapped défense, biotech, santé, banque, administration publique, contextes soumis à l’AI Act européen.

En mode air-gapped, le microservice paddleocr-server peut être pré-provisionné avec ses modèles embarqués, sans aucun appel réseau à l’exécution.

Les binaires cross-plateformes (Windows, macOS Intel, macOS Apple Silicon M1-M4, Linux x86, Linux ARM) sont produits par GitHub Actions et disponibles dans les GitHub Releases. Un jar exécutable compatible Java 17 et supérieur (Java 21 LTS recommandé pour les performances), un double-clic, et l’IDE démarre.

Le repo est ici : github.com/oculix-org/Oculix. Une issue, une PR, un message — tout est bon à prendre.

— Julien Mer, mainteneur OculiX

Plus d’articles comme celui-ci

23 ans après le MIT, l’automatisation visuelle n’a plus besoin d’être commerciale
23 ans après le MIT, l’automatisation visuelle n’a plus besoin d’être commerciale
Apr 22, 2026
import org.sikuli.script.Screen;
import org.sikuli.script.Region;

public class HelloOcr {
    public static void main(String[] args) {
        Screen s = new Screen();
        Region r = s.find("login_button.png");
        String text = r.text();        // OCR sur la zone trouvée
        System.out.println("Texte lu : " + text);
        s.click("Valider");            // Cherche "Valider" en OCR et clique
    }
}
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.By;
import org.sikuli.script.Screen;

public class TestHybride {
    public static void main(String[] args) throws Exception {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://app.metier.fr");

        // Selenium pour le DOM standard
        driver.findElement(By.id("login")).sendKeys("admin");
        driver.findElement(By.cssSelector(".btn-login")).click();

        // OculiX pour ce que Selenium ne peut pas tester
        // (canvas WebGL, PDF embarqué, widget non DOM)
        Screen s = new Screen();
        s.wait("dashboard_canvas_loaded.png", 10);
        s.click("widget_graphique_personnalise.png");

        driver.quit();
    }
}
import org.sikuli.vnc.VNCScreen;
import org.sikuli.script.Pattern;

public class TestCaisseDistante {
    public static void main(String[] args) throws Exception {
        VNCScreen caisse = VNCScreen.start("192.168.42.10", 5900, 10000, 2000);
        caisse.click(new Pattern("menu_caissier.png"));
        caisse.type("article123");
        caisse.click(new Pattern("bouton_valider.png"));
        caisse.stop();
    }
}
import com.sikulix.util.SSHTunnel;
import org.sikuli.vnc.VNCScreen;

public class TestCaisseViaBastion {
    public static void main(String[] args) throws Exception {
        try (SSHTunnel tunnel = SSHTunnel.open("bastion.entreprise.fr", "tester", "***")) {
            VNCScreen caisse = VNCScreen.start("127.0.0.1", tunnel.getLocalPort(), 10000, 2000);
            caisse.click("ecran_accueil_caisse.png");
            // ... actions de test
            caisse.stop();
        } // SSHTunnel.close() automatique via try-with-resources
    }
}