Einführung in NutJS
NutJS – auch als nutjs.dev bekannt – ist eine leistungsstarke Desktop-Automatisierungs-Software für Node.js. Entwickelt von Simon Hofmann aus Rain (Niederbayern), um die Automatisierung von Abläufen auf dem Desktop zu erleichtern, bietet dir NutJS eine einfache und zugängliche Schnittstelle für die Skripterstellung. Mit Funktionen wie Tastatureingaben, Mausbewegungen und Bilderkennung ermöglicht dir NutJS die nahtlose Automatisierung von Desktop-Anwendungen für verschiedene Anwendungsfälle.
Anmerkung: In diesem Beitrag nutze ich die informelle Anrede „du“ und gleichzeitig das generische Maskulinum. Dies dient dazu, eine persönliche Atmosphäre zu schaffen, die den Austausch und das Lernen ansprechender macht. Gleichzeitig erleichtert es den Lesefluss. Dennoch gilt natürlich allen mein höchster Respekt.
Einleitung
Für wen ist dieser Artikel?
Dieser Blog-Beitrag richtet sich an dich, wenn du dich für Desktop-Automatisierung interessierst, egal ob du dich schon länger damit beschäftigst, oder nur einmal hereinschnuppern möchtest. Für das allgemeine Verständnis ist es wichtig, dass du zumindest über Grundkenntnisse in JavaScript/TypeScript und Node.js verfügst. Außerdem gehe ich davon aus, dass Node.js bei dir auch installiert ist.
WICHTIG: Das (kostenlose) NutJS wird maximal bis Node.js-Version 18 LTS unterstützt!
Kosten und Lizenzen
Um NutJS auszuprobieren, gibt es eine kostenlose Lizenz, die du direkt mit npm installieren kannst. Die enthaltenen Funktionalitäten sind bereits sehr mächtig, kommen allerdings auch an Grenzen, wenn du etwas mehr möchtest. Du hast dann die Möglichkeit, ab 40 Dollar monatlich eine entsprechende Lizenz zu erwerben. Je nach Anwendungsgebiet kannst du zwischen dem sogenannten Solo-Plan, für die private Nutzung, und dem Team-Plan, für die kommerzielle Nutzung, wählen. Falls dein Anwendungsgebiet nicht in die Lizenzbedingungen passt, kannst du dich mit dem Entwickler in Verbindung setzen und einen Custom-Plan vereinbaren. Ich selbst habe NutJS mit dem sog. Free-Plan ausprobiert. Folglich werde ich in diesem Tutorial nur auf die kostenlosen Features detailiert eingehen. Gerne darfst du auf der Entwicklerseite auch entdecken, was die kostenpflichtigen Lizenzen beinhalten. Ich werde auch nicht auf alle Funktionalitäten eingehen, das würde den Rahmen dieses Beitrags sprengen. Ich werde dir stattdessen mit trivialen Beispielen einen ersten Einblick geben.
Erste Schritte
Installation
Zuerst richtest du dir ein Node.js-Projekt ein, indem du an geeigneter Stelle einen Ordner – ich nenne ihn hier nutjs-demo
– anlegst und diesen mit dem Befehl
C:\Users\Robert\nutjs-demo>npm init
initialisierst. Dann konfigurierst du die entsprechenden Standard-Module, je nachdem, ob du mit JavaScript oder TypeScript arbeitest. NutJS kannst du mit beidem verwenden – ich selbst arbeite mit TypeScript. Das Grundpaket mit den Core-Funktionalitäten installierst du mit
C:\Users\Robert\nutjs-demo>npm install @nut-tree/nut-js
und die Funktionen für die Bilderkennung mit
C:\Users\Robert\nutjs-demo>npm install @nut-tree/template-matcher
It works on my machine(?)
Aus eigener Erfahrung kann ich sagen, dass die Installation nicht so „einfach“ ist, wie der Entwickler angibt. Ich hatte bei der Verwendung des Template Matchers diverse Fehlermeldungen. Nach einiger Recherche durfte ich erst einmal die zum September 2023 aktuellste Node.js-Version 20 auf 18 LTS downgraden. Dann durfte ich mich Stück für Stück voranarbeiten, und diverse Pakete in meinem Node.js-Projekt manuell nachinstallieren. Solltest du auch möglichweise Schwierigkeiten bei der Installation oder bei der Verwendung haben, stelle ich dir hier ein GitHub-Template zur Verfügung. Lad es dir gerne herunter und pass es deinen Bedürfnissen an. Das sollte die initialen Fehlermeldungen reduzieren oder vielleicht sogar komplett eliminieren.
Los geht’s!
Der Umgang mit NutJS ist im Prinzip sehr einfach, da die Core-Funktionen überschaubar sind, und die Funktionsaufrufe ziemlich intuitiv sind. Das hier sind die Hauptobjekte, die man aus der Bibliothek @nut-tree/nut-js
importieren kann:
clipboard
(für die Zwischenablage)keyboard
(für Tastatureingaben)mouse
(für Mauseingaben)screen
(für Bildschirmabfragen)jestMatchers
(Erweiterung fürexpect
des Jest-Frameworks)
Zwischenablage
Da die Zwischenablage der kostenlosen NutJS-Version auf reinen Text beschränkt ist, verzichte ich hier auf ein Beispiel, weil das meiner Meinung nach nicht sonderlich spannend ist. Falls dich das Feature dennoch interessiert, kannst du es dir gerne auf der Entwicklerseite ansehen. Die beiden Methoden lauten:
clipboard.getContent()
holt den aktuellen Text der Windows-Zwischenablage.clipboard.setContent()
kopiert einen beliebigen Text in die Windows-Zwischenablage.
Tastatureingaben simulieren
Lass uns anfangen, ein paar einfache Tastatureingaben zu simulieren. Das keyboard
-Objekt stellt dabei die folgenden Funktionalitäten zur Verfügung:
keyboard.config keyboard.pressKey() keyboard.releaseKey() keyboard.type()
config
enthält verschiedene Properties, um die Tastaturfunktionen einzustellen (siehe Konfiguration von NutJS-Komponenten).- Mit
pressKey
werden Tastendrücke simuliert. Dabei gelten die Tasten solange als heruntergedrückt, bis man die gleiche Taste mitreleaseKey
wieder freigibt. Also das Code-Pendant zum echten „drück eine Taste“ und „lass die Taste wieder los“. - Mit
type
kannst du das Eingeben ganzer Strings bzw. Texte simulieren, so wie du sie auch selbst mit der Tastatur eintippen würdest. Beim Ausprobieren habe ich herausgefunden. dass man auch einzelne Tasten kurz antippen kann, damit man nicht jedesmalpressKey
undreleaseKey
extra aufrufen muss. Ich werde es in den Beispielen zu Demonstrationszwecken trotzdem tun.
Kommen wir nun zum eigentlichen Beispiel. Wir wollen mithilfe von NutJS den Windows-Editor (notepad.exe) aufrufen, darin den Text „Hallo, Welt.“ eingeben und die Datei unter dem Namen „hallo_welt.txt“ speichern. Hier erstmal der Code:
01: import { keyboard, Key, sleep } from "@nut-tree/nut-js"; 02: 03: async(() => { 04: await keyboard.pressKey(Key.LeftWin, Key.R); 05: await keyboard.releaseKey(Key.LeftWin, Key.R); 06: await keyboard.type("notepad.exe\n"); 07: await sleep(100); 08: await keyboard.type("Hallo, Welt.\n"); 09: await keyboard.pressKey(Key.LeftControl, Key.S); 10: await keyboard.releaseKey(Key.LeftControl, Key.S); 11: await keyboard.type("hallo_welt.txt\n"); 12: await sleep(100); 13: await keyboard.pressKey(Key.LeftAlt, Key.F4); 14: await keyboard.release(Key.LeftAlt, Key.F4); 15: })();
- In Zeile 1 importiere ich nicht nur die
keyboard
-Klasse für die Tastatureingaben, sondern auch den EnumKey
, der alle Tasten der Tastatur als Namen beinhält, und die Funktionsleep
, die ich weiter unten für eine kurze Pause benötige. - Vielleicht ist dir bereits aufgefallen, dass hier in den Zeilen 4 bis 14 vor jeder Anweisung
await
steht. Das liegt daran, dass alle NutJS-Funktionen asynchron ablaufen. Deswegen benötige ich für den Aufruf des Skripts auch einenasync
-Block, wie ich ihn mit den Zeilen 3 und 15 eingeschlossen habe, der dann durch das abschließende()
gleich aufgerufen wird. - In den Zeilen 4 und 5 lasse ich die Tastenkombination
<WINDOWS><R>
drücken, die den Ausführen-Dialog von Windows auruft:
- Dort trage ich mithilfe der
type
-Methode (Zeile 6) den Dateinamen des Windows-Editors ein. Das abschließende\n
am Ende, was bei einer Textausgabe normalerweise einen Zeilenumbruch ausführt, simuliert hier den Druck auf die<ENTER>
– bzw.<RETURN>
-Taste. - In Zeile 7 warte ich 100 Milliskeunden lang, also eine zehntel Sekunde, bis das Programm geladen ist. Diese Angabe ist möglichweise nicht ganz so intuitiv. Vielleicht ist der ein oder andere der Meinung, dass solch eine Zahl standardmäßig für Sekunden oder Millisekunden steht, der andere bevorzugt möglichweise eine Bezeichnung in der Art
Duration.ofMilliseconds()
(siehe unten). Für NutJS nehmen wir das jetzt einfach so hin. Hier geht es lediglich darum, dass eine Anwendung, je nach Größe immer einen Moment benötigt, bis sie geladen ist. - In Zeile 8 gebe ich also den Text „Hallo, Welt.“ ein mit einem abschließenden Zeilenumbruch.
- In den Zeile 9 und 10 drücke ich die Tastenkombination
<CTRL><S>
bzw.<STRG><S>
, was in den meisten Programmen für „Speichern“ steht. Da unsere Datei noch keinen Namen hat, wird hier der „Speichern-Als“-Dialog angezeigt. - In Zeile 11 gebe ich der Datei also den Namen „hallo_welt.txt“ und bestätige auch hier meine Eingabe wie in Zeile 6 durch die Escape-Sequenz
\n
. Ich hätte hier auch einen Pfad wählen können, ich wollte das Beispiel jedoch so einfach wie möglich halten. - In Zeile 12 warte ich wieder eine zehntel Sekunde, bis die Datei gespeichert wurde.
- In den Zeile 13 und 14 beende ich den Editor mithilfe der Tastenkombination
<ALT><F4>
.
Anmerkung: Ich habe hier die Tasten LeftWin
, LeftControl
und LeftAlt
verwendet. Bei den ersten beiden, und bei der <SHIFT>
-Taste, ist es i.d.R. egal, ob man die linke oder die rechte drückt. Bei der <ALT>
-Taste ist das nicht so. Die linke ist die „normale“ <ALT>
-Taste, und die rechte ist die Taste <ALT GR>
.
Die kostenpflichtige Erweiterung der Tastatursimulation beinhaltet sogar eine komplette Unicode-Unterstützung und kann somit bspw. auch Emojis tippen.
Intuitive Zeitangaben
Falls du die Wartezeit bei sleep
etwas leserlicher haben möchtest, stelle ich dir hier den Code meines Scripts Duration.ts
zur Verfügung.
export function ofMilliseconds(milliseconds: number): number { return milliseconds; } export function ofSeconds(seconds: number): number { return seconds * ofMilliseconds(1000); } export function ofMinutes(minutes: number): number { return minutes * ofSeconds(60); } export function ofHours(hours: number): number { return hours * ofMinutes(60); } export function ofDays(days: number): number { return days * ofHours(24); } export function ofWeeks(weeks: number): number { return weeks * ofDays(7); } export function ofYears(years: number): number { return years * ofDays(365); } export function ofLeapYears(years: number): number { return years * ofDays(366); }
Mauseingaben simulieren
Auch den Mauscursor kannst du mit NutJS bewegen. Im unteren Beispiel verwende ich auch Bildschirmabfrage-Funktionen. Diese sind weiter unten noch einmal beschrieben. Für die Mausfunktionen benötigst du das mouse
-Objekt und ggf. entsprechene Richtungsfunktionen. Die Mausfunktionalitäten lauten wie folgt:
mouse.config mouse.move() mouse.getPosition() mouse.setPosition() mouse.click(), mouse.doubleClick(), mouse.leftClick(), mouse.rightClick() mouse.pressButton(), mouse.releaseButton() mouse.drag() mouse.scrollDown(), mouse.scrollLeft(), mouse.scrollRight(), mouse.scrollUp() down(), left(), right(), up() straightTo()
config
enthält verschiedene Properties, um die Mausfunktionen einzustellen (siehe Konfiguration von NutJS-Komponenten).move
bewegt den Mauscursor in eine bestimmte Richtung oder an einen bestimmten Punkt. Je nach konfigurierter Zeigergeschwindigkeit kannst du dabei zusehen, wie sich der Cursor bewegt.getPosition
holt die aktuelle Position des Mauscursors.setPosition
setzt den Mauscursor unmittelbar an einen bestimmten Punkt auf dem Bildschirm.click
,doubleClick
,leftClick
undrightClick
simulieren entsprechende Mausklicks.pressButton
undreleaseButton
simulieren, ähnlich wie beimkeyboard
-Objekt das Drücken oder Loslassen einer Maustaste.drag
zieht das Objekt, auf das der Cursor gerade zeigt, entlang der angegebenen Punkte, die alsPoint
-Array angegeben werden.scrollDown
,scrollLeft
,scrollRight
undscrollUp
simulieren eine Scrollbewegung in die entsprechende Richtung.down
,left
,right
undup
geben an, wohin der Mauscursor bewegt werden soll.straighTo
bewegt bei der Verwendung vonmove
den Mauscursor, ähnlich wiesetPosition
, zu einer bestimmen Position.
Kommen wir zum Beispiel:
01: import { down, left, mouse, Point, right, screen, up } from "@nut-tree/nut-js"; 02: 03: async(() => { 04: const width = await screen.width(); 05: const height = await screen.height(); 06: const halfWidth = Math.floor(width / 2); 07: const halfHeight = Math.floor(height / 2); 08: await mouse.setPosition(new Point(halfWidth, halfHeight)); 09: await mouse.move(right(100)); 10: await mouse.move(down(100)); 11: await mouse.move(left(100)); 12: await mouse.move(up(100)); 13: })();
- In Zeile 1 importiere ich also das
mouse
– und dasscreen
-Objekt, dann die Richtungsfunktionen und den DatentypPoint
, der später noch einmal genauer beschrieben wird. - Desweiteren haben wir hier wieder mehrere
await
-Anweisungen. Ich habe ja bereits erwähnt, dass die NutJS-Funktionen asynchron sind. - In den Zeilen 4 und 5 hole ich mir mithilfe des
screen
-Objekts die aktuelle Bildschirmauflösung in Pixeln. - In den Zeilen 6 und 7 berechne ich mir dann schlicht und einfach die Bildschirmmitte.
- In Zeile 8 setze ich mit der
setPosition
-Methode den Cursor dorthin. Dazu definiere ich vorher mitnew Point()
ein Punkt-Objekt, das die Bildschirmmitte darstellt. - In den Zeilen 9 bis 12 beschreibe ich zu Demozwecken eine Art „Vierecksbewegung“ (100 Pixel).
Bildschirmabfragen
Nun wollen wir uns ‚mal ein bisschen auf dem Bildschirm umschauen. Um Bilder oder Bildausschnitte abzugleichen, benötigst du zusätzlich die Bibliothek @nut-tree/template-matcher
. Die Verwendungsweise sieht du um unteren Beispiel. Das screen
-Objekt enthält folgende Funktionalitäten:
screen.config screen.height(), screen.width() screen.find(), screen.findAll() screen.highlight() screen.waitFor() screen.capture(), screen.captureRegion() screen.grab(), screen.grabRegion()
config
enthält verschiedene Properties, um die Bildschirmfunktionen einzustellen (siehe Konfiguration von NutJS-Komponenten).width
undheight
bestimmen die Bildschirmauflösung (Breite und Höhe) in Pixeln.find
undfindAll
suchen Bildausschnitte am Bildschirm. Es wird der erste bzw. es werden alle gefundenen zurückgegeben.highlight
markiert einen bestimmten Bildschirmausschnitt.waitFor
wartet, bis ein bestimmter Bildschirmausschnitt am Bildschirm sichtbar ist.capture
undcaptureRegion
machen einen Screenshot (komplett oder Bereich) und speichern ihn in eine Datei.grab
undgrabRegion
machen einen Screenshot und liefern das Ergebnis als Objekt vom TypImage
(Bild) zurück.
Beim laden und speichern von Bildern unterstützt NutJS die beiden Bildformate JPEG und PNG. Ob die bezahlten Lizenzen eventuell mehr Formate unterstützen, konnte ich der Dokumentation nicht entnehmen. Doch für die meisten Anwendungsfälle sollten diese beiden Formate genügen. Widmen wir uns einem einfachen Beispiel, wie eine solche Bildschirmabfrage aussehen kann. Ich will einen Bildausschnit laden und ihn am Bildschirm finden lassen.
01: import { loadImage, screen } from "@nut-tree/nut-js"; 02: import "@nut-tree/template-matcher"; 03: 04: async(() => { 05: screen.config.autoHighlight = true; 06: screen.config.confidence = 0.8; 07: const width = await screen.width(); 08: const height = await screen.height(); 09: const image = await loadImage("./example.png"); 10: const position = await screen.find(image); 11: })();
- In Zeile 1 importiere ich die Funktion
loadImage
und dasscreen
-Objekt. - Die Syntax von Zeile 2 ist hier sehr wichtig. Das Modul
template-matcher
wird im Prinzip direkt ausgeführt, weswegen hier weder Funktionen noch Objekte stehen, und auch keinfrom
. Solltest du anstelle derimport
-Anweisung dierequire
-Funktion verwenden, ist die Syntax ähnlich. Du lässt einfach die Zuweisung weg, und schreibst direktrequire("@nut-tree/template-matcher");
. - In Zeile 4 wird wieder der bekannte
async
-Block eingeleitet. - In Zeile 5 möchte ich, dass der gefundene Bildausschnitt am Bildschirm automatisch markiert wird.
- In Zeile 6 lege ich fest, wie ähnlich der Bildausschnitt dem tatsächlich gefundenen sein muss. Darauf gehe ich bei der Konfiguration noch genauer ein.
- Die Zeilen 7 und 8 haben für das Beispiel keine konkrete Funktion, sondern zeigen lediglich noch einmal, wie man die aktuelle Bildschirmauflösung ermittelt.
- In Zeile 9 lade ich eine potenzielle Datei mit dem zu suchenden Bildschirmausschnitt. Wenn du das Beispiel selbst ausprobieren möchtest, empfehle ich dir, einen Screenshot zu machen und davon einen beliebigen Ausschnitt in einer beliebigen Bilddatei abzuspeichern. Dann gibst du diesen Dateinamen als Argument in der Funktion
loadImage
an. - In Zeile 10 ermittle ich dann die Position (als Datentyp
Point
) des gefundenen Ausschnitts.
Konfiguration von NutJS-Komponenten
In diesem Abschnitt will ich die Konfiguration der einzelnen Komponenten innerhalb des Codes aufzeigen, nicht die Einstellungen in einer JSON-Datei. Jedes der oben genannten Objekte hat eine eigene config
-Propery. Dabei kann bei den Objekten folgendes insgesamt eingestellt werden:
keyboard.config.autoDelayMs
: Gibt an, wie viele Millisekunden automatisch zwischen zwei Tastatureingaben gewartet werden soll.mouse.config.autoDelayMs
: Gibt an, wie viele Millisekunden automatisch zwischen zwei Mausklicks gewartet werden soll.mouse.config.mouseSpeed
: Gibt die Geschwindigkeit des Mauscursors in Pixel/Sekunde an.screen.config.autoHighlight
: Gibt an, ob Suchergebnisse auf dem Bildschirm markiert werden sollen (bzw. ob sie kurz aufleuchten sollen).screen.config.confidence
: Ähnlichkeit, mit der zwei Bilder übereinstimmen müssen. Laut Dokumentation ist hier die Ähnlichkeit in Prozent anzugeben. Ich finde das etwas irreführend, da ich beim Ausprobieren festgestellt habe, dass die Prozentzahl als Kommazahl gemeint ist. Das heißt bspw. für eine 80%ige Übereinstimmung gibt man0.8
an. Sollen die Bilder genau übereinstimmen, gibt man1
an.screen.config.highlightDurationMs
: Gibt an, wie lange (in Millisekunden) gefundene Elemente markiert werden sollen.screen.config.highlightOpacity
: Deckungskraft der Markierung.0
ist unsichtbar,0.5
steht für 50%,1
ist komplett deckend.screen.config.resourceDirectory
: Gibt das Standardverzeichnis an, von dem Bilder mit relativem Pfad aus geladen oder gespeichert werden sollen.
Weitere Funktionalitäten in NutJs
Vielleicht sind dir neben den verwendeten Komponenten (clipboard
, keyboard
, mouse
und screen
) auch ein paar weitere Datentypen, Funktionen usw. aufgefallen. Ich will dir hier die wichtigsten aufzählen:
Button
: Enum, der die drei üblichen Maustasten als Namen (LEFT
,MIDDLE
undRIGHT
) enthält.down
: Funktion, um den Mauscursor nach unten zu bewegen.fetchFromUrl
: Lädt ein Bild mit einer angegebenen URL. Dadurch kann man Bilder aus dem Netz laden. Die Bildadresse kann alsstring
oder alsURL
angegeben werden.FileType
: entält die Enum-KonstantenJPG
undPNG
.getActiveWindow
: Holt das aktuell fokussierte Fenster.getWindows
: Liefert eine Liste mit allen geöffneten Anwendungen und Prozessen.Image
: Datentyp für ein Bild mit weiteren Eigenschaften wie Auflösung (Breite und Höhe), Bits/Pixel, Farbkanäle, Farbmodus, usw.isPoint
: Prüft, ob ein Objekt vom DatentypPoint
ist.jestMatchers
: Damit kann manexpect
im die MatchertoBeAt
,toBeIn
undtoShow
erweitern.Key
: Hierbei handelt es sich um einen Enum, der alle Tasten einer üblichen Tastatur als Namen enthält.left
: Funktion, um den Mauscursor nach links zu bewegen.loadImage
: Lädt ein Bild im JPEG- oder PNG-Format von der Festplatte.Point
: Datentyp für einen beliebigen Punkt (x-/y-Koordinate) auf dem Bildschirm.Region
: Datentyp für einen rechteckigen Bereich; enthält die linke, oberen Koordinate und die Ausdehnung (Breite/Höhe); wird u.a. vonWindow
verwendet.RGBA
: Datentyp für eine Farbe mit Rot-, Grün-, Blau- und Alpha-Kanal.right
: Funktion, um den Mauscursor nach rechts zu bewegen.saveImage
: Speichert ein Bild im JPEG- oder PNG-Format auf die Festplatte.sleep
: Wartet mit der weiteren Ausführung für die angegebene Anzahl an Millisekunden.straightTo
: Funktion, um den Mauscursor zu einem bestimmten Punkt hinzubewegen.toBeAt
: Jest-Matcher, um zu prüfen, ob sich der Mauscursor an einem bestmmten Punkt befindet.toBeIn
: Jest-Matcher, um zu prüfen, ob sich der Mauscursor in einem bestimmten Bereich befindet.toShow
: Jest-Matcher, um zu prüfen, ob ein bestimmtes Bild oder ein bestimmter Bildausschnitt am Bildschirm sichtbar ist.up
: Funktion, um den Mauscursor nach oben zu bewegen.URL
: Datentyp, der vonfetchFromUrl
verwendet wird.Window
: Fensterdatentyp; enthält den Namen des Fensters und seine Region, also wo sich das Fenster genau am Bildschim befindet. Wird u.a. vongetActiveWindow
undgetWindows
verwendet.
Und noch mehr Funktionalitäten in NutJs
Ich selbst habe nur die kostenlose NutJS-Lizenz ausprobiert. Wenn du dich dafür entscheiden solltest, dir die kostenpflichtige Lizenz zu holen, stehen dir noch mehr Funktionen zur Verfügung. Du hast dann Zugriff auf folgende Bibliotheken:
@nut-tree/bolt
: Damit kannst du die Funktionalitäten für Bildschirm, Maus, Tastatur und Zwischenablage erweitern. Um das jeweilgie Objekt zu erweitern, rufst du die entsprechende useBolt-Funktion auf. Um bspw. die Tastatur zu erweitern lautet die FunktionuseBoltKeyboard
. Diese hat dann volle Unicode unterstützung. DasWindow
-Objekt bietet u.a. auch einen Fenster-Finder an.@nut-tree/nl-matcher
: Enthält bessere Bilderkennungsfunktionen als der Template-Matcher, u.a. sogar Gesichtserkennung. Außerdem gibt es hierfür einen Long-Term-Support.@nut-tree/plugin-ocr
: Bietet Funktionalitäten zur Texterkennung. Auch auf dem Bildschirm kann dort Text erkannt werden, um bspw. Menüs leichter auffinden zu können.
Zusamenfassung
Die einzige, kleine Schwäche, die ich entdeckt habe, ist beim Ablauf eines Skripts, auch wenn man bspw. gerade einen Test laufen lässt, dass man nicht „hineinfunken“ darf. Das heißt, man sollte währenddessen keine Taste drücken und auch die Maus in Ruhe lassen. Da ein PC üblicherweise nur eine einzige Tastatur und nur eine einzige Maus hat, kann auch NutJS nur diese beiden einzigen ansteuern. Insgesamt kann ich jedoch sagen, dass NutJS im Bezug auf Desktop-Automatisierung Potenzial hat. Nur die kostenlosen Features stoßen schnell an ihre Grenzen, und es gibt auch leider keine Möglichkeit, die Pro-Features für einen kleinen Zeitraum kostenlos zu testen, wie man es von anderer kommerzieller Software kennt. Mit der bezahlten Lizenz kann man sicher noch mehr herausholen. Wenn du bis hierhin gelesen hast, danke ich dir für deine Aufmerksamkeit. Und wenn du zusätzlich auch auf den Geschmack gekommen bist, wünsche dir viel Spaß beim Ausprobieren. Lass deiner Kreativität freien Lauf! Bei Fragen und Anregungen freue ich mich auf einen Kommentar von dir, und bin selbstverständlich auch offen für konstruktive Kritik.
Quellenangaben
- Entwicklerseite von NutJS: https://nutjs.dev
- Simon Hofmann auf LinkedIn: https://de.linkedin.com/in/simon-hofmann-959230119
- Website von Simon Hofmann: https://s1h.org/
- Repository (Basic-Demo): https://github.com/RLK-ST/nutjs-demo
Tätigkeiten im Bereich Software und Qualitätssicherung
Die IT ist mein Zauhause. Egal, ob Entwicklung oder Testautomatisierung:
wenn es darum geht, ein qualitatives Produkt zu liefern, bin ich dabei!
Hinterlasse einen Kommentar
An der Diskussion beteiligen?Hinterlasse uns deinen Kommentar!