scenes->current()?->exit(); $this->db?->close(); parent::tearDown(); } public function testTheTableData(): void { $form = $this->connected(); $this->openTable($form, 'customers'); $this->keep('data'); } public function testTheStructure(): void { $form = $this->connected(); $this->openTable($form, 'orders'); $form->click($form->widget('tabStructure')); $this->game->run(30); $this->keep('structure'); } public function testTheSqlEditor(): void { $form = $this->connected(); $this->openTable($form, 'customers'); // the connection and the database chosen $form->click($form->widget('tabSql')); $this->game->run(2); $sql = "SELECT c.name, c.city, COUNT(o.id) AS orders, SUM(o.total) AS spent\n" . "FROM customers c JOIN orders o ON o.customer_id = c.id\n" . "GROUP BY c.id ORDER BY spent DESC;"; $form->widget('editor')->setText($sql); $form->runSql($sql); $this->until(fn () => $form->lastResults() !== [], 'the result (' . $form->widget('resultInfo')->props['text'] . ')'); $this->game->run(10); $this->keep('sql'); } public function testTheDarkTheme(): void { $form = $this->connected(); $this->openTable($form, 'products'); $dark = $form->widget('dark'); $dark->checked = true; $form->onDarkChange($dark, true); $this->game->run(10); $this->keep('dark'); } private function connected(): MainForm { $this->db = TestServer::connect(); if ($this->db === null) { self::markTestSkipped('No test server (see tests/TestServer.php)'); } $this->seed($this->db); $this->game->start(MainForm::class, ['connect' => TestServer::config() + ['database' => self::DB]]); /** @var MainForm $form */ $form = $this->game->scene(); $this->until(fn () => $form->widget('tree')->node($this->node('customers')) !== null, 'the tables'); return $form; } private function openTable(MainForm $form, string $table): void { $form->widget('tree')->select($this->node($table)); $this->until(fn () => $form->page() !== null && $form->total() !== null, "the rows of $table"); $this->game->run(10); } private function node(string $table): string { return "t\x1ftest\x1f" . self::DB . "\x1f" . $table; } private function until(callable $ready, string $what): void { for ($i = 0; $i < 400; $i++) { if ($ready()) { return; } $this->game->run(1); usleep(2000); } self::fail("Waited too long: $what"); } private function keep(string $name): void { $file = $this->game->shot('site-' . $name); $out = dirname(__DIR__, 2) . '/var/site-shots'; @mkdir($out, 0777, true); copy($file, "$out/$name.png"); self::assertFileExists("$out/$name.png"); } private function seed(MysqlConnection $db): void { $d = self::DB; $db->wait($db->query(<<