Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Default build wait before the timeout exception is thrown by the test
default.project.build.wait=90800000
default.project.flash.wait=60000
Comment thread
AndriiFilippov marked this conversation as resolved.

# Default project copy delay before the timeout exception is thrown
default.project.copy.wait=7000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import java.util.Arrays;
import java.util.Optional;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
Expand Down Expand Up @@ -130,6 +129,7 @@ public boolean test() throws Exception
view.show();
view.setFocus();
String textString = view.bot().styledText().getText();

return textString.toLowerCase().contains(text.toLowerCase());
}

Expand All @@ -140,6 +140,25 @@ public String getFailureMessage()
}
}, timeOut, 3000);
}

public static void waitUntilTextContains(SWTWorkbenchBot bot, String text, SWTBotView terminalView, long timeOut) {
terminalView.bot().waitUntil(new DefaultCondition() {
@Override
public boolean test() throws Exception {

String terminalText = terminalView.bot().canvas().getText();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kolipakakondal @alirana01 hi guys !

I need your advice. I'm writing a test for the Serial Monitor but can't extract text from the Terminal view.
Using SWT Inspector, I found that the terminal content is a textCanvas , not text() or styledText() , so it returns an empty string.
Since Canvas has no methods to get the content, I’m not sure how to proceed.

return terminalText.toLowerCase().contains(text.toLowerCase());
}

@Override
public String getFailureMessage() {
return "Text not found in terminal!";
}
}, timeOut, 3000); // Wait for up to 'timeOut' milliseconds
}
Comment on lines +144 to +159

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Terminal text read uses Canvas.getText() (nonexistent) — switch to StyledText

SWT Canvas doesn’t expose text. This will fail at runtime/compile-time depending on bindings. Use styledText like elsewhere and ensure the view is visible/focused before reading.

- public static void waitUntilTextContains(SWTWorkbenchBot bot, String text, SWTBotView terminalView, long timeOut) {
-     terminalView.bot().waitUntil(new DefaultCondition() {
+ public static void waitUntilTextContains(SWTWorkbenchBot bot, String text, SWTBotView terminalView, long timeOut) {
+     terminalView.bot().waitUntil(new DefaultCondition() {
          @Override
          public boolean test() throws Exception {
-             
-             String terminalText = terminalView.bot().canvas().getText();
-             
-             return terminalText.toLowerCase().contains(text.toLowerCase());
+             terminalView.show();
+             terminalView.setFocus();
+             String terminalText = terminalView.bot().styledText().getText();
+             return terminalText.toLowerCase().contains(text.toLowerCase());
          }
 
          @Override
          public String getFailureMessage() {
              return "Text not found in terminal!";
          }
-     }, timeOut, 3000);  // Wait for up to 'timeOut' milliseconds
+     }, timeOut, 3000);
  }

Optional: de-duplicate with waitUntilViewContains by reusing it for terminal checks.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static void waitUntilTextContains(SWTWorkbenchBot bot, String text, SWTBotView terminalView, long timeOut) {
terminalView.bot().waitUntil(new DefaultCondition() {
@Override
public boolean test() throws Exception {
String terminalText = terminalView.bot().canvas().getText();
return terminalText.toLowerCase().contains(text.toLowerCase());
}
@Override
public String getFailureMessage() {
return "Text not found in terminal!";
}
}, timeOut, 3000); // Wait for up to 'timeOut' milliseconds
}
public static void waitUntilTextContains(SWTWorkbenchBot bot, String text, SWTBotView terminalView, long timeOut) {
terminalView.bot().waitUntil(new DefaultCondition() {
@Override
public boolean test() throws Exception {
terminalView.show();
terminalView.setFocus();
String terminalText = terminalView.bot().styledText().getText();
return terminalText.toLowerCase().contains(text.toLowerCase());
}
@Override
public String getFailureMessage() {
return "Text not found in terminal!";
}
}, timeOut, 3000);
}
🤖 Prompt for AI Agents
In
tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/common/utility/TestWidgetWaitUtility.java
around lines 144 to 159, the method reads terminal text via
terminalView.bot().canvas().getText() which is invalid; replace that with
retrieving the StyledText widget (e.g. find the StyledText in the view's bot or
use terminalView.bot().styledText().getText()), ensure the terminal view is
visible/focused before reading (call terminalView.show() /
terminalView.setFocus() or use waitUntil on view visibility), and optionally
call the existing waitUntilViewContains helper to avoid duplication by
delegating terminal checks to it.




/**
* Waits until the tree contains an item which contains the name in its text
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*******************************************************************************
* Copyright 2025 Espressif Systems (Shanghai) PTE LTD. All rights reserved.
* Use is subject to license terms.
*******************************************************************************/
package com.espressif.idf.ui.test.executable.cases.project;
import java.io.IOException;

import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;

import com.espressif.idf.ui.test.common.WorkBenchSWTBot;
import com.espressif.idf.ui.test.common.utility.TestWidgetWaitUtility;
import com.espressif.idf.ui.test.operations.EnvSetupOperations;
import com.espressif.idf.ui.test.operations.ProjectTestOperations;

/**
* Test class to test the Serial Monitor feature
*
* @author Andrii Filippov
*
*/
@SuppressWarnings("restriction")
@RunWith(SWTBotJunit4ClassRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class NewEspressifIDFProjectSerialMonitorTest
{
@BeforeClass
public static void beforeTestClass() throws Exception
{
Fixture.loadEnv();
}

@After
public void afterEachTest()
{
try
{
Fixture.cleanTestEnv(); // Make sure test environment is always cleaned up
}
catch (Exception e)
{
System.err.println("Error during cleanup: " + e.getMessage());
}
}

@Test
public void givenNewProjectCreatedBuiltWhenFlashProjectThenCheckSerialMonitorOutput()
throws Exception
{
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Typo breaks project template selection (“EspressIf” → “Espressif”)

Category is case-sensitive in the UI. This will fail to locate the wizard node.

- Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
+ Fixture.givenNewEspressifIDFProjectIsSelected("Espressif", "Espressif IDF Project");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
Fixture.givenNewEspressifIDFProjectIsSelected("Espressif", "Espressif IDF Project");
🤖 Prompt for AI Agents
In
tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/NewEspressifIDFProjectSerialMonitorTest.java
around line 57, the fixture call uses the wrong-cased category string
"EspressIf" causing the UI wizard node lookup to fail; replace the string with
the correct, case-sensitive "Espressif" so the template/category matches the UI
exactly and the wizard node can be located.

Fixture.givenProjectNameIs("NewProjectSerialMonitorTest");
Fixture.whenNewProjectIsSelected();
Fixture.whenProjectIsBuiltUsingContextMenu();
Fixture.whenFlashProject();
Fixture.whenSelectSerialPort();
Fixture.whenFlashProject();
Fixture.openSerialMonitorandVerify();
}

private static class Fixture
{
private static SWTWorkbenchBot bot;
private static String category;
private static String subCategory;
private static String projectName;

private static void loadEnv() throws Exception
{
bot = WorkBenchSWTBot.getBot();
EnvSetupOperations.setupEspressifEnv(bot);
bot.sleep(1000);
}

private static void givenNewEspressifIDFProjectIsSelected(String category, String subCategory)
{
Fixture.category = category;
Fixture.subCategory = subCategory;
}

private static void givenProjectNameIs(String projectName)
{
Fixture.projectName = projectName;
}

private static void whenNewProjectIsSelected() throws Exception
{
ProjectTestOperations.setupProject(projectName, category, subCategory, bot);
}

private static void whenProjectIsBuiltUsingContextMenu() throws IOException
{
ProjectTestOperations.buildProjectUsingContextMenu(projectName, bot);
ProjectTestOperations.waitForProjectBuild(bot);
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
}

private static void whenFlashProject() throws IOException
{
ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Run Configurations...");
TestWidgetWaitUtility.waitForDialogToAppear(bot, "Run Configurations", 10000);
SWTBotShell prefrencesShell = bot.shell("Run Configurations");
prefrencesShell.bot().tree().getTreeItem("ESP-IDF Application").select();
prefrencesShell.bot().tree().getTreeItem("ESP-IDF Application").expand();
prefrencesShell.bot().tree().getTreeItem("ESP-IDF Application").getNode("NewProjectSerialMonitorTest").select();
bot.sleep(1000);
bot.button("Run").click();
}

private static void whenSelectSerialPort() throws IOException
{
TestWidgetWaitUtility.waitForDialogToAppear(bot, "Serial port not found", 30000);
bot.button("OK").click();
TestWidgetWaitUtility.waitForDialogToAppear(bot, "New ESP Target", 20000);
bot.comboBoxWithLabel("Serial Port:").setSelection("COM5 USB Serial Port (COM5)");
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
bot.button("Finish").click();
}
Comment on lines +116 to +124

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Port selection is Windows-specific (“COM5”); make it portable or property-driven

Linux/macOS won’t have COM5. Read a property and fallback to the first item to keep CI portable.

- bot.comboBoxWithLabel("Serial Port:").setSelection("COM5 USB Serial Port (COM5)");
+ String preferredPort = DefaultPropertyFetcher.getStringPropertyValue("default.serial.port.label", "");
+ if (preferredPort != null && !preferredPort.isEmpty()) {
+     bot.comboBoxWithLabel("Serial Port:").setSelection(preferredPort);
+ } else {
+     bot.comboBoxWithLabel("Serial Port:").setSelection(0); // fallback: first available
+ }

Add missing import at the top of this file:

import com.espressif.idf.ui.test.common.configs.DefaultPropertyFetcher;


private static void openSerialMonitorandVerify() throws IOException {
ProjectTestOperations.waitProjectFlash(bot);
ProjectTestOperations.waitForProjectMonitorAndDisconnect(bot);
ProjectTestOperations.findTextInSerialMonitorOutput(bot);
}

private static void cleanTestEnv()
{
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
ProjectTestOperations.closeAllProjects(bot);
ProjectTestOperations.deleteAllProjects(bot);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public class ProjectTestOperations
{

private static final String DEFAULT_PROJECT_BUILD_WAIT_PROPERTY = "default.project.build.wait";

private static final String DEFAULT_FLASH_WAIT_PROPERTY = "default.project.build.wait";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Wrong property key for flash timeout (causes hours-long waits)

DEFAULT_FLASH_WAIT_PROPERTY points to the build-wait key. This makes flash waits use 90,800,000 ms from the Linux config.

- private static final String DEFAULT_FLASH_WAIT_PROPERTY = "default.project.build.wait";
+ private static final String DEFAULT_FLASH_WAIT_PROPERTY = "default.project.flash.wait";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private static final String DEFAULT_FLASH_WAIT_PROPERTY = "default.project.build.wait";
private static final String DEFAULT_FLASH_WAIT_PROPERTY = "default.project.flash.wait";
🤖 Prompt for AI Agents
In
tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/ProjectTestOperations.java
around line 56, the constant DEFAULT_FLASH_WAIT_PROPERTY is set to the
build-wait key causing flash operations to pick up the wrong (very large)
timeout; change the string value from "default.project.build.wait" to the
correct flash timeout key (e.g. "default.project.flash.wait"), update any
references if needed, and run the tests to confirm flash waits now use the
intended timeout.


private static final Logger logger = LoggerFactory.getLogger(ProjectTestOperations.class);

Expand Down Expand Up @@ -99,6 +101,25 @@ public static void waitForProjectNewComponentInstalled(SWTWorkbenchBot bot) thro
DefaultPropertyFetcher.getLongPropertyValue("Install New Component", 10000));
}

public static void waitForProjectMonitorAndDisconnect(SWTWorkbenchBot bot) throws IOException
{
bot.sleep(5000);
SWTBotView terminalView = viewTerminal("COM5", bot, 30000);
terminalView.toolbarPushButton("Disconnect Terminal Connection").click();
terminalView.show();
terminalView.setFocus();
}

public static void findTextInSerialMonitorOutput(SWTWorkbenchBot bot) throws IOException
{
bot.sleep(5000);
SWTBotView terminalView = viewTerminal("<Closed> COM5", bot, 30000);
terminalView.show();
terminalView.setFocus();
TestWidgetWaitUtility.waitUntilTextContains(bot, "Hello", terminalView,
DefaultPropertyFetcher.getLongPropertyValue(DEFAULT_FLASH_WAIT_PROPERTY, 20000));
}

public static SWTBotView viewConsole(String consoleType, SWTWorkbenchBot bot)
{
SWTBotView view = bot.viewByPartName("Console");
Expand All @@ -110,6 +131,22 @@ public static SWTBotView viewConsole(String consoleType, SWTWorkbenchBot bot)
view.setFocus();
return view;
}

public static SWTBotView viewTerminal(String terminalType, SWTWorkbenchBot bot, long timeOut)
{
SWTBotView view = bot.viewByPartName("Terminal");
view.show();
view.setFocus();
return view;
}

public static void waitProjectFlash(SWTWorkbenchBot bot) throws IOException
{
SWTBotView view = bot.viewByPartName("Console");
view.setFocus();
TestWidgetWaitUtility.waitUntilViewContains(bot, "Hard resetting via RTS pin...", view,
DefaultPropertyFetcher.getLongPropertyValue(DEFAULT_FLASH_WAIT_PROPERTY, 40000));
}

public static void createDebugConfiguration(String projectName, SWTWorkbenchBot bot)
{
Expand Down
Loading