feat(editor): F4.6e the e-mail program and e-mail server on a computer's desktop
The oracle MailWindowRun uses Java's e-mail windows as a person does and answers their dialogs. The core sets and saves the program's account, deletes a mail, checks a form as Java's window does, and gives the server its domain, new and removed accounts and the window's own line; the room sends both programs' views and takes their actions; the editor has both windows. Better than Java: a name field for a new account, a user name the server has is refused, deleting hits the folder shown, a new domain goes into the accounts file at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1332,3 +1332,39 @@ Gemessen (03.10.2026):
|
||||
`StringTokenizer` die Leerzeilen, und die Zelle einer unvollständigen
|
||||
Zeile rückt in die davor. Liegt die Datei da, ist das Kästchen nach dem
|
||||
nächsten Start wieder an, auch abgeschaltet.
|
||||
|
||||
### E-Mail-Programm und E-Mail-Server (F4.6e)
|
||||
|
||||
`MailWindowRun` öffnet Javas `GUIApplicationEmailServerWindow` und
|
||||
`GUIApplicationEmailAnwendungWindow` auf je einem `GUIDesktopPanel` im Netz
|
||||
von mail-lan und benutzt sie wie eine Person: am Server Startknopf,
|
||||
Domainfeld, das Formular „Neues Konto“ (der Knopf hört auf `mousePressed`,
|
||||
nicht auf eine Aktion), Konten-Liste und Entfernen; im Programm den
|
||||
Konto-Dialog, das Fenster zum Verfassen (seine Felder und Knöpfe auf dem
|
||||
Desktop), Abrufen, eine gewählte Mail, Antworten, Löschen. Javas
|
||||
Meldungsdialoge beantwortet ein Wächter-Thread wie eine Person (OK, „Ja“)
|
||||
und schreibt ihren Text mit (`packages/sim/test/mailWindow.java.json`).
|
||||
|
||||
Gemessen (03.10.2026):
|
||||
|
||||
* Der Server: „Starten“/„Anhalten“; das Fenster selbst, nicht der Server,
|
||||
schreibt „POP3- und SMTP-Server wurden gestartet.“/„… angehalten.“ ins
|
||||
Log. Die Domain nimmt nur, was `musterDomain` nimmt, und nur angehalten
|
||||
(das Feld ist sonst gesperrt); die Konten-Liste zeigt danach die neue
|
||||
Domain, `konten.txt` die alte bis zur nächsten Kontenänderung.
|
||||
* Neues Konto: ohne Name oder Passwort `emailserver_msg25`, mit Leerzeichen
|
||||
`msg24`; das Formular hat das Etikett „Vorname und Nachname:“, aber kein
|
||||
Feld — jedes Konto heißt „Vorname Nachname“. Ein vorhandener Name (auch
|
||||
in anderer Schreibweise) wird nicht angelegt, das Fenster meldet trotzdem
|
||||
„Das Benutzerkonto … wurde angelegt.“ Entfernen fragt erst.
|
||||
* Das Programm: Der Konto-Dialog prüft die Ports (`musterPort`) und den
|
||||
Benutzernamen (`musterEmailBenutzername`, leer geht), sonst
|
||||
`emailanwendung_msg46`; der Name wird geteilt (letztes Wort Nachname) und
|
||||
`/konten.txt` geschrieben. Verfassen prüft die Adressen (`msg20`) und
|
||||
verlangt einen Empfänger (`msg21`); gesendet schließt das Fenster und
|
||||
zeigt „Gesendete“, Abrufen den Posteingang. Zeilen: Absendername (sonst
|
||||
Adresse) bzw. die Empfängerliste wie `holeEmpfaengerListe`; Antworten
|
||||
schreibt an den Absender, „RE: …“ und den Text zitiert unter „… schrieb:“.
|
||||
* Löschen löscht in Javas Fenster die Zeile der zuletzt **angeklickten**
|
||||
Liste: War zuvor eine gesendete Mail gewählt und ist im Posteingang schon
|
||||
eine markiert, geht die gesendete.
|
||||
|
||||
@@ -21,7 +21,7 @@ if [ ! -f "$upstream/target/filius.jar" ]; then
|
||||
fi
|
||||
classpath="$upstream/target/filius.jar:$upstream/target/lib/*"
|
||||
mkdir -p "$here/.build"
|
||||
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" "$here/src/WlanRun.java" "$here/src/ExampleRun.java" "$here/src/EchoRun.java" "$here/src/WebRun.java" "$here/src/RouterWebRun.java" "$here/src/KonfigCases.java" "$here/src/EmailRun.java" "$here/src/MailCases.java" "$here/src/EmailClientRun.java" "$here/src/TerminalCases.java" "$here/src/TerminalRun.java" "$here/src/FileCases.java" "$here/src/GnutellaRun.java" "$here/src/NewDeviceRun.java" "$here/src/SheetRun.java" "$here/src/TerminalWindowRun.java" "$here/src/InstallRun.java" "$here/src/BrowserWindowRun.java"
|
||||
javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" "$here/src/WlanRun.java" "$here/src/ExampleRun.java" "$here/src/EchoRun.java" "$here/src/WebRun.java" "$here/src/RouterWebRun.java" "$here/src/KonfigCases.java" "$here/src/EmailRun.java" "$here/src/MailCases.java" "$here/src/EmailClientRun.java" "$here/src/TerminalCases.java" "$here/src/TerminalRun.java" "$here/src/FileCases.java" "$here/src/GnutellaRun.java" "$here/src/NewDeviceRun.java" "$here/src/SheetRun.java" "$here/src/TerminalWindowRun.java" "$here/src/InstallRun.java" "$here/src/BrowserWindowRun.java" "$here/src/MailWindowRun.java"
|
||||
# FILIUS writes its settings below $HOME; keep them out of the real one.
|
||||
mkdir -p "$here/.build/home"
|
||||
# Removed first: a crashed run must not leave the previous result standing.
|
||||
@@ -378,6 +378,17 @@ HOME="$here/.build/home" xvfb-run -a java -Duser.language=de -Duser.country=DE -
|
||||
"$root/packages/core/test/scenarios/web-lan.scenario.json" "$output" 2>&1 | grep -v 'logback\|^$\|^\s*at \|AWT-EventQueue' || true
|
||||
test -s "$output"
|
||||
|
||||
# FILIUS' e-mail server and e-mail program windows used as a person does —
|
||||
# the server switched, its domain set, accounts made and removed; the
|
||||
# program's account set, mails written, sent, fetched, answered and deleted,
|
||||
# Java's dialogs answered — on mail-lan's network (MailWindowRun): the room's
|
||||
# e-mail windows (packages/sim/test/mailWindow.test.ts).
|
||||
output="$root/packages/sim/test/mailWindow.java.json"
|
||||
rm -f "$output"
|
||||
HOME="$here/.build/home" xvfb-run -a java -Duser.language=de -Duser.country=DE -cp "$classpath:$here/.build" MailWindowRun \
|
||||
"$root/packages/core/test/scenarios/mail-lan.scenario.json" "$output" 2>&1 | grep -v 'logback\|^$\|^\s*at \|AWT-EventQueue' || true
|
||||
test -s "$output"
|
||||
|
||||
# FILIUS' own examples as Java FILIUS runs them, opened and started as FILIUS
|
||||
# does (ExampleRun): the acceptance of F2 (packages/fls/test/examplesJava.test.ts)
|
||||
# and the classics of F3 (web, email, gnutella; packages/fls/test/classicsJava.test.ts).
|
||||
|
||||
@@ -0,0 +1,356 @@
|
||||
// Uses FILIUS' own e-mail server and e-mail program windows
|
||||
// (GUIApplicationEmailServerWindow, GUIApplicationEmailAnwendungWindow on
|
||||
// their GUIDesktopPanels) on mail-lan's network as a person does: the
|
||||
// server's start button, its domain field, its form for a new account (the
|
||||
// button's mouse listener, as Java's window listens), the account list and
|
||||
// its delete button; the program's account dialog, its compose window (the
|
||||
// fields and buttons of the window it shows on the desktop), fetching, a mail
|
||||
// chosen, answered and deleted. Java's message dialogs are answered as a
|
||||
// person would (OK, "yes" to a question) and their text is written down.
|
||||
// After each step it writes what the windows show: the server's button,
|
||||
// domain field, account rows, log and its accounts file; the program's
|
||||
// folders' rows, preview, the compose window's fields and its accounts file.
|
||||
// The reference for the editor's e-mail windows
|
||||
// (packages/sim/test/mailWindow.test.ts).
|
||||
//
|
||||
// Usage: java -cp filius.jar:lib/*:classes MailWindowRun <scenario.json> <output json>
|
||||
|
||||
import filius.gui.anwendungssicht.GUIApplicationEmailAnwendungWindow;
|
||||
import filius.gui.anwendungssicht.GUIApplicationEmailServerWindow;
|
||||
import filius.gui.anwendungssicht.GUIDesktopPanel;
|
||||
import filius.software.email.EmailServer;
|
||||
import filius.software.system.Betriebssystem;
|
||||
import filius.software.system.Datei;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPasswordField;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
public class MailWindowRun {
|
||||
static final String CLIENT = "00000000-0000-0000-0000-000000000201";
|
||||
static final String SERVER = "00000000-0000-0000-0000-000000000203";
|
||||
|
||||
static final List<Object> steps = new ArrayList<>();
|
||||
/** The texts of Java's message dialogs since the last step. */
|
||||
static final List<String> dialogs = new ArrayList<>();
|
||||
|
||||
static Object field(Class<?> owner, Object object, String name) throws Exception {
|
||||
Field field = owner.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
return field.get(object);
|
||||
}
|
||||
|
||||
static List<List<String>> rows(JTable table) {
|
||||
List<List<String>> rows = new ArrayList<>();
|
||||
TableModel model = table.getModel();
|
||||
for (int row = 0; row < model.getRowCount(); row++) {
|
||||
List<String> cells = new ArrayList<>();
|
||||
for (int column = 0; column < model.getColumnCount(); column++) cells.add(String.valueOf(model.getValueAt(row, column)));
|
||||
rows.add(cells);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
static List<String> takeDialogs() {
|
||||
synchronized (dialogs) {
|
||||
List<String> taken = new ArrayList<>(dialogs);
|
||||
dialogs.clear();
|
||||
return taken;
|
||||
}
|
||||
}
|
||||
|
||||
/** Answers each message dialog as a person would: OK, or "yes" to a question; writes down its text. */
|
||||
static void watchDialogs() {
|
||||
Thread watcher = new Thread(() -> {
|
||||
while (true) {
|
||||
for (Window window : Window.getWindows()) {
|
||||
if (!(window instanceof JDialog) || !window.isVisible()) continue;
|
||||
JOptionPane pane = find((Container) window, JOptionPane.class);
|
||||
if (pane == null) continue;
|
||||
synchronized (dialogs) {
|
||||
dialogs.add(String.valueOf(pane.getMessage()));
|
||||
}
|
||||
pane.setValue(pane.getOptionType() == JOptionPane.DEFAULT_OPTION ? JOptionPane.OK_OPTION : JOptionPane.YES_OPTION);
|
||||
window.setVisible(false);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException error) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
watcher.setDaemon(true);
|
||||
watcher.start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T> T find(Container container, Class<T> kind) {
|
||||
for (Component component : container.getComponents()) {
|
||||
if (kind.isInstance(component)) return (T) component;
|
||||
if (component instanceof Container) {
|
||||
T found = find((Container) component, kind);
|
||||
if (found != null) return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static <T> List<T> all(Container container, Class<T> kind, List<T> found) {
|
||||
for (Component component : container.getComponents()) {
|
||||
if (kind.isInstance(component)) found.add(kind.cast(component));
|
||||
if (component instanceof Container) all((Container) component, kind, found);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
static AbstractButton button(Container container, String text) {
|
||||
for (AbstractButton each : all(container, AbstractButton.class, new ArrayList<>())) if (text.equals(each.getText())) return each;
|
||||
throw new IllegalStateException("no button " + text);
|
||||
}
|
||||
|
||||
static void onEdt(Runnable action) throws Exception {
|
||||
SwingUtilities.invokeLater(action);
|
||||
Thread.sleep(400);
|
||||
}
|
||||
|
||||
/** A press with the mouse, as Java's server window listens (mousePressed, not an action). */
|
||||
static void press(AbstractButton button) throws Exception {
|
||||
onEdt(() -> {
|
||||
MouseEvent event = new MouseEvent(button, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), 0, 5, 5, 1, false);
|
||||
for (MouseListener listener : button.getMouseListeners()) listener.mousePressed(event);
|
||||
});
|
||||
}
|
||||
|
||||
static String file(Betriebssystem system, String path) {
|
||||
Datei datei = system.getDateisystem().holeDatei(path);
|
||||
return datei == null ? null : datei.getDateiInhalt();
|
||||
}
|
||||
|
||||
static void serverStep(GUIApplicationEmailServerWindow window, Betriebssystem system, String step) throws Exception {
|
||||
Class<?> type = GUIApplicationEmailServerWindow.class;
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("step", step);
|
||||
result.put("button", ((JButton) field(type, window, "startStopButton")).getText());
|
||||
JTextField domain = (JTextField) field(type, window, "domainField");
|
||||
result.put("domain", domain.getText());
|
||||
result.put("domainEnabled", domain.isEnabled());
|
||||
result.put("accounts", rows((JTable) field(type, window, "kontenListenTabelle")));
|
||||
result.put("username", ((JTextField) field(type, window, "benutzernameField")).getText());
|
||||
result.put("log", ((JTextArea) field(type, window, "logArea")).getText());
|
||||
result.put("accountsFile", file(system, "/mailserver/konten.txt"));
|
||||
result.put("dialogs", takeDialogs());
|
||||
steps.add(result);
|
||||
}
|
||||
|
||||
static void clientStep(GUIApplicationEmailAnwendungWindow window, GUIDesktopPanel desktop, Betriebssystem system, String step) throws Exception {
|
||||
Class<?> type = GUIApplicationEmailAnwendungWindow.class;
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
result.put("step", step);
|
||||
result.put("inbox", rows((JTable) field(type, window, "posteingangTable")));
|
||||
result.put("sent", rows((JTable) field(type, window, "gesendeteTable")));
|
||||
result.put("tab", ((JTabbedPane) field(type, window, "tabbedPane")).getSelectedIndex());
|
||||
JEditorPane preview = (JEditorPane) field(type, window, "emailVorschau");
|
||||
result.put("preview", preview.getContentType().equals("text/plain") ? preview.getText() : "html");
|
||||
JPanel compose = (JPanel) field(type, window, "verfassenPanel");
|
||||
boolean composing = compose != null && compose.getParent() != null;
|
||||
result.put("composing", composing);
|
||||
if (composing) {
|
||||
List<String> fields = new ArrayList<>();
|
||||
for (JTextField each : all(compose, JTextField.class, new ArrayList<>())) fields.add(each.getText());
|
||||
result.put("composeFields", fields);
|
||||
result.put("composeText", find(compose, JTextArea.class).getText());
|
||||
JComboBox<?> sender = find(compose, JComboBox.class);
|
||||
result.put("composeSender", sender.getSelectedItem() == null ? null : sender.getSelectedItem().toString());
|
||||
}
|
||||
result.put("accountFile", file(system, "/konten.txt"));
|
||||
result.put("dialogs", takeDialogs());
|
||||
steps.add(result);
|
||||
}
|
||||
|
||||
static void waitFor(java.util.function.BooleanSupplier condition, long milliseconds) throws Exception {
|
||||
long until = System.currentTimeMillis() + milliseconds;
|
||||
while (System.currentTimeMillis() < until && !condition.getAsBoolean()) Thread.sleep(100);
|
||||
Thread.sleep(1500);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
run(args);
|
||||
} catch (Throwable error) {
|
||||
error.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static void run(String[] args) throws Exception {
|
||||
ScenarioNetwork network = ScenarioNetwork.read(args[0]);
|
||||
Betriebssystem serverSystem = (Betriebssystem) network.nodes.get(SERVER).getSystemSoftware();
|
||||
Betriebssystem clientSystem = (Betriebssystem) network.nodes.get(CLIENT).getSystemSoftware();
|
||||
serverSystem.installApp("filius.software.email.EmailServer", false);
|
||||
clientSystem.installApp("filius.software.email.EmailAnwendung", false);
|
||||
EmailServer server = (EmailServer) serverSystem.holeSoftware("filius.software.email.EmailServer");
|
||||
network.start();
|
||||
Thread.sleep(500);
|
||||
watchDialogs();
|
||||
|
||||
JFrame frame = new JFrame();
|
||||
GUIDesktopPanel serverDesktop = new GUIDesktopPanel(serverSystem);
|
||||
GUIDesktopPanel clientDesktop = new GUIDesktopPanel(clientSystem);
|
||||
frame.getContentPane().setLayout(new java.awt.FlowLayout());
|
||||
frame.getContentPane().add(serverDesktop);
|
||||
frame.getContentPane().add(clientDesktop);
|
||||
GUIApplicationEmailServerWindow serverWindow = (GUIApplicationEmailServerWindow) serverDesktop.starteAnwendung("filius.software.email.EmailServer");
|
||||
GUIApplicationEmailAnwendungWindow window = (GUIApplicationEmailAnwendungWindow) clientDesktop.starteAnwendung("filius.software.email.EmailAnwendung");
|
||||
SwingUtilities.invokeAndWait(() -> {
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
});
|
||||
Thread.sleep(500);
|
||||
|
||||
Class<?> serverType = GUIApplicationEmailServerWindow.class;
|
||||
JTextField domain = (JTextField) field(serverType, serverWindow, "domainField");
|
||||
JTextField username = (JTextField) field(serverType, serverWindow, "benutzernameField");
|
||||
JPasswordField password = (JPasswordField) field(serverType, serverWindow, "passwortField");
|
||||
JButton startStop = (JButton) field(serverType, serverWindow, "startStopButton");
|
||||
AbstractButton addAccount = (AbstractButton) field(serverType, serverWindow, "addButton");
|
||||
|
||||
serverStep(serverWindow, serverSystem, "server:open");
|
||||
for (String typed : new String[] { "ungültig domain!", "schule.de" }) {
|
||||
onEdt(() -> {
|
||||
domain.setText(typed);
|
||||
domain.postActionEvent();
|
||||
});
|
||||
serverStep(serverWindow, serverSystem, "server:domain " + typed);
|
||||
}
|
||||
onEdt(startStop::doClick);
|
||||
serverStep(serverWindow, serverSystem, "server:start");
|
||||
for (String[] account : new String[][] { { "anna", "geheim" }, { "", "x" }, { "carl os", "x" }, { "ANNA", "anders" }, { "bob", "" }, { "bob", "pw" } }) {
|
||||
onEdt(() -> {
|
||||
username.setText(account[0]);
|
||||
password.setText(account[1]);
|
||||
});
|
||||
press(addAccount);
|
||||
serverStep(serverWindow, serverSystem, "server:add " + account[0] + "/" + account[1]);
|
||||
}
|
||||
|
||||
// The program: its account, first with a user name Java does not take, then as it should be.
|
||||
Class<?> clientType = GUIApplicationEmailAnwendungWindow.class;
|
||||
clientStep(window, clientDesktop, clientSystem, "client:open");
|
||||
String[][] accounts = { { "Anna Maria Muster", "anna@schule.de", "192.168.0.30", "110", "192.168.0.30", "25", "an na", "geheim" },
|
||||
{ "Anna Maria Muster", "anna@schule.de", "192.168.0.30", "110x", "192.168.0.30", "25", "anna", "geheim" },
|
||||
{ "Anna Maria Muster", "anna@schule.de", "192.168.0.30", "110", "192.168.0.30", "25", "anna", "geheim" } };
|
||||
for (String[] account : accounts) {
|
||||
onEdt(((AbstractButton) field(clientType, window, "buttonKonten"))::doClick);
|
||||
String[] names = { "tfName", "tfEmailAdresse", "tfPOP3Server", "tfPOP3Port", "tfSMTPServer", "tfSMTPPort", "tfBenutzername", "tfPasswort" };
|
||||
onEdt(() -> {
|
||||
try {
|
||||
for (int index = 0; index < names.length; index++) ((JTextField) field(clientType, window, names[index])).setText(account[index]);
|
||||
} catch (Exception error) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
});
|
||||
onEdt(button(clientDesktop, "Speichern")::doClick);
|
||||
clientStep(window, clientDesktop, clientSystem, "client:account " + account[6] + " " + account[3]);
|
||||
// A dialog Java leaves open after a failure: closed as a person would.
|
||||
for (AbstractButton cancel : all(clientDesktop, AbstractButton.class, new ArrayList<>())) {
|
||||
if (cancel.getText() != null && cancel.getText().equals("Abbrechen") && cancel.isShowing()) onEdt(cancel::doClick);
|
||||
}
|
||||
}
|
||||
// Opened again, the dialog shows the account.
|
||||
onEdt(((AbstractButton) field(clientType, window, "buttonKonten"))::doClick);
|
||||
Map<String, Object> shown = new LinkedHashMap<>();
|
||||
shown.put("step", "client:account shown");
|
||||
List<String> fields = new ArrayList<>();
|
||||
for (String name : new String[] { "tfName", "tfEmailAdresse", "tfPOP3Server", "tfPOP3Port", "tfSMTPServer", "tfSMTPPort", "tfBenutzername", "tfPasswort" }) {
|
||||
fields.add(((JTextField) field(clientType, window, name)).getText());
|
||||
}
|
||||
shown.put("fields", fields);
|
||||
steps.add(shown);
|
||||
onEdt(button(clientDesktop, "Abbrechen")::doClick);
|
||||
|
||||
// Mails: written in the compose window, with addresses Java does not take, none, then to bob and to anna herself.
|
||||
String[][] mails = { { "bob@schule.de, kein", "", "", "Falsch", "x" }, { "", "", "", "Leer", "x" }, { "bob@schule.de", "", "", "Hallo", "Zeile 1\nZeile 2" },
|
||||
{ "anna@schule.de", "", "", "Selbst", "Erste Zeile\nZweite Zeile" } };
|
||||
for (String[] mail : mails) {
|
||||
JPanel open = (JPanel) field(clientType, window, "verfassenPanel");
|
||||
if (open == null || open.getParent() == null) onEdt(((AbstractButton) field(clientType, window, "buttonMailVerfassen"))::doClick);
|
||||
JPanel compose = (JPanel) field(clientType, window, "verfassenPanel");
|
||||
onEdt(() -> {
|
||||
List<JTextField> boxes = all(compose, JTextField.class, new ArrayList<>());
|
||||
for (int index = 0; index < 4; index++) boxes.get(index).setText(mail[index]);
|
||||
find(compose, JTextArea.class).setText(mail[4]);
|
||||
});
|
||||
int before = ((JTable) field(clientType, window, "gesendeteTable")).getRowCount();
|
||||
onEdt(button(compose, "Senden")::doClick);
|
||||
JTable sent = (JTable) field(clientType, window, "gesendeteTable");
|
||||
if (!mail[0].isEmpty() && !mail[0].contains("kein")) waitFor(() -> sent.getRowCount() > before, 20000);
|
||||
clientStep(window, clientDesktop, clientSystem, "client:send " + mail[3]);
|
||||
}
|
||||
serverStep(serverWindow, serverSystem, "server:after mails");
|
||||
|
||||
onEdt(((AbstractButton) field(clientType, window, "buttonMailsAbholen"))::doClick);
|
||||
JTable inbox = (JTable) field(clientType, window, "posteingangTable");
|
||||
waitFor(() -> inbox.getRowCount() > 0, 20000);
|
||||
clientStep(window, clientDesktop, clientSystem, "client:fetch");
|
||||
onEdt(() -> inbox.setRowSelectionInterval(0, 0));
|
||||
clientStep(window, clientDesktop, clientSystem, "client:choose inbox 0");
|
||||
onEdt(((AbstractButton) field(clientType, window, "buttonMailAntworten"))::doClick);
|
||||
clientStep(window, clientDesktop, clientSystem, "client:answer");
|
||||
onEdt(button((JPanel) field(clientType, window, "verfassenPanel"), "Abbrechen")::doClick);
|
||||
JTable sent = (JTable) field(clientType, window, "gesendeteTable");
|
||||
onEdt(() -> sent.setRowSelectionInterval(0, 0));
|
||||
clientStep(window, clientDesktop, clientSystem, "client:choose sent 0");
|
||||
onEdt(() -> inbox.setRowSelectionInterval(0, 0));
|
||||
onEdt(((AbstractButton) field(clientType, window, "buttonEmailLoeschen"))::doClick);
|
||||
clientStep(window, clientDesktop, clientSystem, "client:delete inbox 0");
|
||||
serverStep(serverWindow, serverSystem, "server:after fetch");
|
||||
|
||||
// The server: an account chosen and deleted (Java asks), then stopped.
|
||||
JTable list = (JTable) field(serverType, serverWindow, "kontenListenTabelle");
|
||||
onEdt(() -> list.setRowSelectionInterval(1, 1));
|
||||
press((AbstractButton) field(serverType, serverWindow, "deleteButton"));
|
||||
serverStep(serverWindow, serverSystem, "server:delete row 1");
|
||||
onEdt(startStop::doClick);
|
||||
serverStep(serverWindow, serverSystem, "server:stop");
|
||||
onEdt(() -> {
|
||||
domain.setText("neu.de");
|
||||
domain.postActionEvent();
|
||||
});
|
||||
serverStep(serverWindow, serverSystem, "server:domain neu.de");
|
||||
steps.add(Map.of("step", "server:accounts", "accounts", String.valueOf(server.getListeBenutzerkonten().size())));
|
||||
|
||||
Map<String, Object> output = new LinkedHashMap<>();
|
||||
output.put("steps", steps);
|
||||
try (FileOutputStream out = new FileOutputStream(args[1])) {
|
||||
out.write((FlsOracle.Json.write(output, "") + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
network.stop();
|
||||
System.out.println("mail window steps: " + steps.size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user