From 8512c1524ea60834d2f8e43b8f2dcf3b73b475fe Mon Sep 17 00:00:00 2001 From: AndriiFilippov Date: Fri, 20 Feb 2026 18:05:09 +0100 Subject: [PATCH] feat: add additional targets support for Build&Flash test case --- ...ewEspressifIDFProjectFlashProcessTest.java | 137 +++++++++----- .../selectors/LaunchBarTargetSelector.java | 177 +++++++++--------- 2 files changed, 178 insertions(+), 136 deletions(-) diff --git a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/NewEspressifIDFProjectFlashProcessTest.java b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/NewEspressifIDFProjectFlashProcessTest.java index 28206bbdb..f06e2b8b5 100644 --- a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/NewEspressifIDFProjectFlashProcessTest.java +++ b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/NewEspressifIDFProjectFlashProcessTest.java @@ -30,115 +30,158 @@ /** * Test class to test the Flash process - * + * * @author Andrii Filippov * */ @SuppressWarnings("restriction") @RunWith(SWTBotJunit4ClassRunner.class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) - -public class NewEspressifIDFProjectFlashProcessTest -{ +public class NewEspressifIDFProjectFlashProcessTest { @BeforeClass - public static void beforeTestClass() throws Exception - { + public static void beforeTestClass() throws Exception { Fixture.loadEnv(); } @AfterClass - public static void tearDown() - { + public static void tearDown() { Fixture.cleanupEnvironment(); } @Test - public void givenNewProjectCreatedBuiltWhenSelectSerialPortWhenFlashThenCheckFlashedSuccessfully() throws Exception - { + public void givenNewProjectCreatedBuiltWhenSelectSerialPortWhenFlashThenCheckFlashedSuccessfully() + throws Exception { if (SystemUtils.IS_OS_LINUX) // temporary solution until new ESP boards arrive for Windows { Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project"); Fixture.givenProjectNameIs("NewProjectFlashTest"); Fixture.whenNewProjectIsSelected(); Fixture.whenTurnOffOpenSerialMonitorAfterFlashingInLaunchConfig(); - Fixture.whenProjectIsBuiltUsingContextMenu(); - Fixture.whenSelectLaunchTargetSerialPort(); - Fixture.whenFlashProject(); - Fixture.thenVerifyFlashDoneSuccessfully(); - } - else - { + Fixture.whenBuildAndFlashForAllTargetsSequentially(); + } else { assertTrue(true); } } - private static class Fixture - { + 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 - { + private static final TargetPort[] TARGETS = new TargetPort[] { + new TargetPort("esp32", "/dev/ttyUSB1 Dual RS232-HS"), +// new TargetPort("esp32s2", ""), +// new TargetPort("esp32s3", ""), +// new TargetPort("esp32h2", ""), +// new TargetPort("esp32c5", ""), +// new TargetPort("esp32c6", ""), +// new TargetPort("esp32p4", "") + }; + + private static void loadEnv() throws Exception { bot = WorkBenchSWTBot.getBot(); EnvSetupOperations.setupEspressifEnv(bot); bot.sleep(1000); ProjectTestOperations.deleteAllProjects(bot); } - private static void givenNewEspressifIDFProjectIsSelected(String category, String subCategory) - { + private static void givenNewEspressifIDFProjectIsSelected(String category, String subCategory) { Fixture.category = category; Fixture.subCategory = subCategory; } - private static void givenProjectNameIs(String projectName) - { + private static void givenProjectNameIs(String projectName) { Fixture.projectName = projectName; } - private static void whenNewProjectIsSelected() throws Exception - { + private static void whenNewProjectIsSelected() throws Exception { ProjectTestOperations.setupProject(projectName, category, subCategory, bot); } - private static void whenProjectIsBuiltUsingContextMenu() throws IOException - { + private static void whenBuildAndFlashForAllTargetsSequentially() throws Exception { + for (int i = 0; i < TARGETS.length; i++) { + TargetPort tp = TARGETS[i]; + + boolean skipTargetChangeDialog = (i == 0); + whenChangeLaunchTarget(tp.target, skipTargetChangeDialog); + + whenProjectIsBuiltUsingContextMenu(); + whenSelectLaunchTargetSerialPort(tp.port); + whenFlashProject(); + thenVerifyFlashDoneSuccessfully(); + + TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot); + bot.sleep(500); + } + } + + private static void whenChangeLaunchTarget(String targetText, boolean skipDialogOnThisRun) throws Exception { + // skip first iteration since esp32 target was selected during Project Creation + if (!skipDialogOnThisRun) { + LaunchBarTargetSelector targetSelector = new LaunchBarTargetSelector(bot); + targetSelector.selectTarget(targetText); + TestWidgetWaitUtility.waitForDialogToAppear(bot, "IDF Launch Target Changed", 20000); + SWTBotShell shell = bot.shell("IDF Launch Target Changed"); + shell.setFocus(); + bot.button("Yes").click(); + } + + TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot); + } + + private static void whenProjectIsBuiltUsingContextMenu() throws IOException { ProjectTestOperations.buildProjectUsingContextMenu(projectName, bot); ProjectTestOperations.waitForProjectBuild(bot); TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot); } - private static void whenSelectLaunchTargetSerialPort() throws Exception - { + private static void whenSelectLaunchTargetSerialPort(String portPrefixOrExact) throws Exception { LaunchBarTargetSelector targetSelector = new LaunchBarTargetSelector(bot); targetSelector.clickEdit(); + TestWidgetWaitUtility.waitForDialogToAppear(bot, "New ESP Target", 20000); SWTBotShell shell = bot.shell("New ESP Target"); - bot.comboBoxWithLabel("Serial Port:").setSelection("/dev/ttyUSB1 Dual RS232-HS"); + try { + bot.comboBoxWithLabel("Serial Port:").setSelection(portPrefixOrExact); + } catch (Exception ignored) { + String[] items = bot.comboBoxWithLabel("Serial Port:").items(); + String match = null; + + for (String item : items) { + if (item != null && item.startsWith(portPrefixOrExact)) { + match = item; + break; + } + } + + if (match == null) { + throw new AssertionError("No serial port matched: " + portPrefixOrExact + " ; available=" + + String.join(", ", items)); + } + + bot.comboBoxWithLabel("Serial Port:").setSelection(match); + } + TestWidgetWaitUtility.waitForOperationsInProgressToFinishSync(bot); shell.setFocus(); bot.button("Finish").click(); } - private static void whenTurnOffOpenSerialMonitorAfterFlashingInLaunchConfig() throws Exception - { + private static void whenTurnOffOpenSerialMonitorAfterFlashingInLaunchConfig() throws Exception { LaunchBarConfigSelector configSelector = new LaunchBarConfigSelector(bot); configSelector.clickEdit(); TestWidgetWaitUtility.waitForDialogToAppear(bot, "Edit Configuration", 20000); bot.cTabItem("Main").show(); bot.cTabItem("Main").setFocus(); SWTBotCheckBox checkBox = bot.checkBox("Open Serial Monitor After Flashing"); - if (checkBox.isChecked()) - { + if (checkBox.isChecked()) { checkBox.click(); } bot.button("OK").click(); } - private static void whenFlashProject() throws IOException - { + private static void whenFlashProject() throws IOException { ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Run Configurations..."); TestWidgetWaitUtility.waitForDialogToAppear(bot, "Run Configurations", 10000); bot.tree().getTreeItem("ESP-IDF Application").select(); @@ -148,16 +191,24 @@ private static void whenFlashProject() throws IOException bot.button("Run").click(); } - private static void thenVerifyFlashDoneSuccessfully() throws Exception - { + private static void thenVerifyFlashDoneSuccessfully() throws Exception { ProjectTestOperations.waitForProjectFlash(bot); } - static void cleanupEnvironment() - { + static void cleanupEnvironment() { TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot); ProjectTestOperations.closeAllProjects(bot); ProjectTestOperations.deleteAllProjects(bot); } + + private static class TargetPort { + final String target; + final String port; + + TargetPort(String target, String port) { + this.target = target; + this.port = port; + } + } } -} +} \ No newline at end of file diff --git a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java index 6bc2938ab..0bbaf0634 100644 --- a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java +++ b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java @@ -37,33 +37,27 @@ */ @SuppressWarnings("restriction") @SWTBotWidget(clasz = CSelector.class, preferredName = "cselector") -public class LaunchBarTargetSelector extends AbstractSWTBotControl -{ +public class LaunchBarTargetSelector extends AbstractSWTBotControl { private static final int NUM_FOR_FILTER_POPUP = 7; - public LaunchBarTargetSelector(TargetSelector targetSelector) throws WidgetNotFoundException - { + public LaunchBarTargetSelector(TargetSelector targetSelector) throws WidgetNotFoundException { super(targetSelector); } - public LaunchBarTargetSelector(SWTBot bot) - { + public LaunchBarTargetSelector(SWTBot bot) { this(bot.widget(WidgetMatcherFactory.withTooltip("Launch Target: OK"))); } - public LaunchBarTargetSelector(SWTBot bot, boolean exec) - { + public LaunchBarTargetSelector(SWTBot bot, boolean exec) { this(bot.widget(WidgetMatcherFactory.widgetOfType(TargetSelector.class))); } - public SWTBot bot() - { + public SWTBot bot() { return new SWTBot(widget); } - public void click(int x, int y) - { + public void click(int x, int y) { notify(SWT.MouseEnter); notify(SWT.MouseMove); notify(SWT.Activate); @@ -72,27 +66,23 @@ public void click(int x, int y) notify(SWT.MouseUp, createMouseEvent(x, y, 1, SWT.BUTTON1, 1)); } - public void clickEdit() - { + public void clickEdit() { bot().canvasWithId(LaunchBarWidgetIds.EDIT).click(); // $NON-NLS-1$ } - private void clickOnInternalWidget(int x, int y, Widget internalWidget) - { + private void clickOnInternalWidget(int x, int y, Widget internalWidget) { notify(SWT.MouseDown, createMouseEvent(x, y, 1, SWT.NONE, 1), internalWidget); notify(SWT.MouseUp, createMouseEvent(x, y, 1, SWT.BUTTON1, 1), internalWidget); } @Override - public LaunchBarTargetSelector click() - { + public LaunchBarTargetSelector click() { Point size = syncExec((Result) () -> widget.getSize()); click(size.x / 2, size.y / 2); return this; } - public LaunchBarTargetSelector select(String text) - { + public LaunchBarTargetSelector select(String text) { click(); Label itemToSelect = bot().shellWithId(LaunchBarWidgetIds.POPUP).bot().widget(withText(text)); Point itemToSelectLocation = syncExec((Result) () -> itemToSelect.getLocation()); @@ -100,82 +90,83 @@ public LaunchBarTargetSelector select(String text) return this; } - public LaunchBarTargetSelector selectTarget(String text) - { - click(); - SWTBotShell swtBotShell = bot().shellWithId(LaunchBarWidgetIds.POPUP); - ScrolledComposite scrolledComposite = swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class)); - int numberOfItemsInScrolledComp = syncExec( - () -> ((Composite) scrolledComposite.getChildren()[0]).getChildren().length); - Label itemToSelect; - - if (numberOfItemsInScrolledComp > NUM_FOR_FILTER_POPUP) - { - swtBotShell.bot().text().setText(text); - itemToSelect = swtBotShell.bot().widget(allOf(widgetOfType(Label.class), withText(text))); - } - else - { - itemToSelect = swtBotShell.bot().widget(allOf(widgetOfType(Label.class), withText(text))); - } - - Point itemToSelectLocation = syncExec((Result) itemToSelect::getLocation); - clickOnInternalWidget(itemToSelectLocation.x, itemToSelectLocation.y, itemToSelect); - return this; + public LaunchBarTargetSelector selectTarget(String text) { + click(); + SWTBotShell swtBotShell = bot().shellWithId(LaunchBarWidgetIds.POPUP); + ScrolledComposite scrolledComposite = swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class)); + + int numberOfItemsInScrolledComp = syncExec( + () -> ((Composite) scrolledComposite.getChildren()[0]).getChildren().length); + + // If popup is "long" (no filter) we may need to scroll to reach items near the + // bottom. + if (numberOfItemsInScrolledComp <= NUM_FOR_FILTER_POPUP) { + scrollToBottom(scrolledComposite); + } + + Label itemToSelect; + + if (numberOfItemsInScrolledComp > NUM_FOR_FILTER_POPUP) { + // Filter pop-up: typing should bring the item into view, no need to scroll. + swtBotShell.bot().text().setText(text); + itemToSelect = swtBotShell.bot().widget(allOf(widgetOfType(Label.class), withText(text))); + } else { + // Non-filter pop-up: try to find it; if not found (still off-screen), scroll + // and retry. + try { + itemToSelect = swtBotShell.bot().widget(allOf(widgetOfType(Label.class), withText(text))); + } catch (Exception firstTryFailed) { + scrollToBottom(scrolledComposite); + itemToSelect = swtBotShell.bot().widget(allOf(widgetOfType(Label.class), withText(text))); + } + } + + // Ensure selection is visible and coordinates are updated after scrolling + Point itemToSelectLocation = syncExec((Result) itemToSelect::getLocation); + clickOnInternalWidget(itemToSelectLocation.x, itemToSelectLocation.y, itemToSelect); + + return this; } - public void scrollToBottom(ScrolledComposite scrolledComposite) - { - syncExec(() -> { - scrolledComposite.setOrigin(0, scrolledComposite.getClientArea().height); - }); + public void scrollToBottom(ScrolledComposite scrolledComposite) { + syncExec(() -> { + scrolledComposite.setOrigin(0, scrolledComposite.getClientArea().height); + }); } - public boolean isTargetPresent(String text) - { - click(); - - try - { - SWTBotShell swtBotShell = bot().shellWithId(LaunchBarWidgetIds.POPUP); - ScrolledComposite scrolledComposite = swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class)); - - int numberOfItemsInScrolledComp = syncExec(() -> - ((Composite) scrolledComposite.getChildren()[0]).getChildren().length - ); - - // Scroll to the bottom if there are many items - if (numberOfItemsInScrolledComp > NUM_FOR_FILTER_POPUP) - { - scrollToBottom(swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class))); - swtBotShell.bot().text().setText(text); - - List labels = swtBotShell.bot().widgets(widgetOfType(Label.class)); - for (Label label : labels) - { - String labelText = syncExec(label::getText); - if (labelText.equals(text)) - { - return true; - } - } - return false; - } - else - { - Widget itemToCheck = swtBotShell.bot().widget(withText(text)); - String labelText = syncExec(() -> ((Label) itemToCheck).getText()); - return labelText.equals(text); - } - } - catch (WidgetNotFoundException e) - { - return false; - } - catch (Exception e) - { - e.printStackTrace(); - return false; - } + public boolean isTargetPresent(String text) { + click(); + + try { + SWTBotShell swtBotShell = bot().shellWithId(LaunchBarWidgetIds.POPUP); + ScrolledComposite scrolledComposite = swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class)); + + int numberOfItemsInScrolledComp = syncExec( + () -> ((Composite) scrolledComposite.getChildren()[0]).getChildren().length); + + // Scroll to the bottom if there are many items + if (numberOfItemsInScrolledComp > NUM_FOR_FILTER_POPUP) { + scrollToBottom(swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class))); + swtBotShell.bot().text().setText(text); + + List labels = swtBotShell.bot().widgets(widgetOfType(Label.class)); + for (Label label : labels) { + String labelText = syncExec(label::getText); + if (labelText.equals(text)) { + return true; + } + } + return false; + } else { + Widget itemToCheck = swtBotShell.bot().widget(withText(text)); + String labelText = syncExec(() -> ((Label) itemToCheck).getText()); + return labelText.equals(text); + } + } catch (WidgetNotFoundException e) { + return false; + } catch (Exception e) { + e.printStackTrace(); + return false; + } } }