Skip to content
Merged
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
@@ -0,0 +1,243 @@
/*******************************************************************************
* Copyright 2021 Espressif Systems (Shanghai) PTE LTD. All rights reserved.
* Use is subject to license terms.
*******************************************************************************/
package com.espressif.idf.ui.test.executable.cases.project;

import static org.junit.Assert.assertTrue;

import java.io.IOException;

import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
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 SBOM feature
*
* @author Andrii Filippov
*
*/
Comment on lines +25 to +30

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

Update JavaDoc to reflect the correct purpose of the test class

The JavaDoc comment incorrectly states this is a test class for the "SBOM feature", but the class actually tests the Partition Table Editor functionality.

Apply this diff to correct the JavaDoc:

 /**
- * Test class to test the SBOM feature
+ * Test class to validate the Partition Table Editor functionality
  * 
  * @author Andrii Filippov
  *
  */
📝 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
/**
* Test class to test the SBOM feature
*
* @author Andrii Filippov
*
*/
/**
* Test class to validate the Partition Table Editor functionality
*
* @author Andrii Filippov
*
*/

@SuppressWarnings("restriction")
@RunWith(SWTBotJunit4ClassRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
Comment on lines +32 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider removing test dependencies.

The use of @FixMethodOrder(MethodSorters.NAME_ASCENDING) suggests that tests are dependent on execution order. This is an anti-pattern in unit testing as it makes tests brittle and harder to maintain.

Consider:

  1. Making each test independent by setting up its own test state
  2. Using appropriate @Before methods for common setup
  3. Removing the @FixMethodOrder annotation once tests are independent

public class NewEspressifIDFProjectPartitionTableEditorTest
{
@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 givenNewProjectCreatedNotBuiltWhenOpenEmptyPartitionTableEditorThenInformationPopUpMessage()
throws Exception
{
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
Fixture.givenProjectNameIs("NewProjectPartitionTableEditor1Test");
Fixture.whenNewProjectIsSelected();
Fixture.whenOpenEmptyPartitionTableEditor();
Fixture.ThenInformationMessagePopUp();
}

@Test
public void givenNewProjectCreatedBuiltWhenOpenPartitionTableEditorThenBuiltInPartitionTableDisplayed()
throws Exception
{
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
Fixture.givenProjectNameIs("NewProjectPartitionTableEditor2Test");
Fixture.whenNewProjectIsSelected();
Fixture.whenProjectIsBuiltUsingContextMenu();
Fixture.whenOpenPartitionTableEditor();
Fixture.ThenBuiltInPartitionTableDisplayed();
}

@Test
public void givenNewProjectCreatedBuiltWhenOpenPartitionTableEditorWhenAddRowThenCheckRowAdded() throws Exception
{
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
Fixture.givenProjectNameIs("NewProjectPartitionTableEditor3Test");
Fixture.whenNewProjectIsSelected();
Fixture.whenProjectIsBuiltUsingContextMenu();
Fixture.whenOpenPartitionTableEditor();
Fixture.whenAddRowToPartitionTable();
Fixture.ThenCheckRowAdded();
}

@Test
public void givenNewProjectCreatedBuiltWhenOpenPartitionTableEditorWhenDeleteSelectedRowThenCheckRowDeleted()
throws Exception
{
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
Fixture.givenProjectNameIs("NewProjectPartitionTableEditor4Test");
Fixture.whenNewProjectIsSelected();
Fixture.whenProjectIsBuiltUsingContextMenu();
Fixture.whenOpenPartitionTableEditor();
Fixture.whenDeleteRowFromPartitionTable();
Fixture.ThenCheckRowDeleted();
}

@Test
public void givenNewProjectCreatedBuiltWhenOpenPartitionTableEditorWhenDeleteSelectedRowWhenSaveAndQuitwhenReopenPartitionTableThenCheckChangesSaved()
throws Exception
{
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
Fixture.givenProjectNameIs("NewProjectPartitionTableEditor5Test");
Fixture.whenNewProjectIsSelected();
Fixture.whenProjectIsBuiltUsingContextMenu();
Fixture.whenOpenPartitionTableEditor();
Fixture.whenDeleteRowFromPartitionTable();
Fixture.whenSaveAndQuit();
Fixture.whenOpenPartitionTableEditor();
Fixture.thenCheckChangesSaved();
}

@Test
public void givenNewProjectCreatedBuiltWhenOpenPartitionTableEditorWhenDeleteSelectedRowWhenSaveAndCancelwhenReopenPartitionTableThenCheckChangesSaved()
throws Exception
{
Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project");
Fixture.givenProjectNameIs("NewProjectPartitionTableEditor6Test");
Fixture.whenNewProjectIsSelected();
Fixture.whenProjectIsBuiltUsingContextMenu();
Fixture.whenOpenPartitionTableEditor();
Fixture.whenDeleteRowFromPartitionTable();
Fixture.whenSavePartitionTable();
Fixture.whenCancel();
Fixture.whenOpenPartitionTableEditor();
Fixture.thenCheckChangesSaved();
}

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);
}
Comment on lines +141 to +146

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid using fixed delays like bot.sleep(1000);

Using fixed delays can lead to flaky tests due to variable execution times. Instead, use explicit wait conditions provided by SWTBot to wait for specific UI elements or operations to complete.

Apply this diff to replace bot.sleep(1000); with a proper wait condition:

 private static void loadEnv() throws Exception
 {
     bot = WorkBenchSWTBot.getBot();
     EnvSetupOperations.setupEspressifEnv(bot);
-    bot.sleep(1000);
+    TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
 }
📝 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 void loadEnv() throws Exception
{
bot = WorkBenchSWTBot.getBot();
EnvSetupOperations.setupEspressifEnv(bot);
bot.sleep(1000);
}
private static void loadEnv() throws Exception
{
bot = WorkBenchSWTBot.getBot();
EnvSetupOperations.setupEspressifEnv(bot);
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
}


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 whenOpenPartitionTableEditor() throws IOException
{
ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Partition Table Editor");
TestWidgetWaitUtility.waitUntilDialogIsNotVisible(bot, "Partition Table Editor", 10000);
}
Comment on lines +171 to +175

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add proper wait conditions for UI interactions.

UI operations like opening editors and clicking buttons need proper wait conditions to prevent flaky tests.

Apply these improvements:

 private static void whenOpenPartitionTableEditor() throws IOException
 {
+    TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
     ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Partition Table Editor");
     TestWidgetWaitUtility.waitUntilDialogIsNotVisible(bot, "Partition Table Editor", 10000);
+    TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
 }

 private static void whenAddRowToPartitionTable() throws IOException
 {
+    TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
     bot.toolbarButton("Add Row").click();
+    TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
 }

Also applies to: 194-197


private static void whenOpenEmptyPartitionTableEditor() throws IOException
{
ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Partition Table Editor");
TestWidgetWaitUtility.waitUntilDialogIsNotVisible(bot, "Information", 10000);
}

private static void ThenInformationMessagePopUp() throws IOException
{
assertTrue(ProjectTestOperations.checkShellContent(bot, "Information",
"Failed to get partition CSV file name from sdkconfig. Make sure your project is compiled and has sdkconfig."));
}
Comment on lines +183 to +187

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Follow Java naming conventions for method names

Method names starting with uppercase letters don't follow Java naming conventions. Please update them to start with lowercase letters.

-private static void ThenInformationMessagePopUp()
+private static void thenInformationMessagePopUp()

-private static void ThenBuiltInPartitionTableDisplayed()
+private static void thenBuiltInPartitionTableDisplayed()

-private static void ThenCheckRowAdded()
+private static void thenCheckRowAdded()

-private static void ThenCheckRowDeleted()
+private static void thenCheckRowDeleted()

Also applies to: 181-184, 191-194, 201-204, 223-226


private static void ThenBuiltInPartitionTableDisplayed() throws IOException
{
assertTrue(ProjectTestOperations.checkPartitionTableContent(bot));
}

private static void whenAddRowToPartitionTable() throws IOException
{
bot.toolbarButton("Add Row").click();
}

private static void ThenCheckRowAdded() throws IOException
{
assertTrue(ProjectTestOperations.comparePartitionTableRows(bot, 1));
}
Comment on lines +194 to +202

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add retry mechanism for UI interactions.

UI interactions like clicking buttons and checking table contents can be flaky. Consider adding a retry mechanism with appropriate waits.

 private static void whenAddRowToPartitionTable() throws IOException
 {
+    TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
     bot.toolbarButton("Add Row").click();
+    TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
 }

 private static void ThenCheckRowAdded() throws IOException
 {
+    // Retry up to 3 times with a short delay
+    for (int i = 0; i < 3; i++) {
+        if (ProjectTestOperations.comparePartitionTableRows(bot, 1)) {
+            return;
+        }
+        TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
+    }
     assertTrue(ProjectTestOperations.comparePartitionTableRows(bot, 1));
 }
📝 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 void whenAddRowToPartitionTable() throws IOException
{
bot.toolbarButton("Add Row").click();
}
private static void ThenCheckRowAdded() throws IOException
{
assertTrue(ProjectTestOperations.comparePartitionTableRows(bot, 1));
}
private static void whenAddRowToPartitionTable() throws IOException
{
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
bot.toolbarButton("Add Row").click();
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
}
private static void ThenCheckRowAdded() throws IOException
{
// Retry up to 3 times with a short delay
for (int i = 0; i < 3; i++) {
if (ProjectTestOperations.comparePartitionTableRows(bot, 1)) {
return;
}
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
}
assertTrue(ProjectTestOperations.comparePartitionTableRows(bot, 1));
}


private static void whenDeleteRowFromPartitionTable() throws IOException
{
ProjectTestOperations.deletePartitionTableRow(bot);
}

private static void ThenCheckRowDeleted() throws IOException
{
assertTrue(ProjectTestOperations.comparePartitionTableRows(bot, -1));
}

private static void whenSaveAndQuit() throws IOException
{
bot.button("Save and Quit").click();
bot.button("OK").click();
}

private static void whenSavePartitionTable() throws IOException
{
bot.toolbarButton("Save").click();
bot.button("OK").click();
}

private static void whenCancel() throws IOException
{
bot.button("Cancel").click();
}

private static void thenCheckChangesSaved() throws IOException
{
assertTrue(ProjectTestOperations.comparePartitionTableRows(bot, -1));
}

private static void cleanTestEnv()
{
TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
ProjectTestOperations.closeAllProjects(bot);
ProjectTestOperations.deleteAllProjects(bot);
}
Comment on lines +236 to +241

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Handle potential exceptions within the method.

The cleanTestEnv method currently does not handle potential exceptions. Consider adding exception handling to ensure the test environment is cleaned up properly even if an error occurs.

private static void cleanTestEnv() {
	try {
		TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot);
		ProjectTestOperations.closeAllProjects(bot);
		ProjectTestOperations.deleteAllProjects(bot);
	} catch (Exception e) {
		// Log the exception and proceed with cleanup
		e.printStackTrace();
	}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ public void givenNewIDFProjectIsSelectedThenProjectIsCreatedAndAddedToProjectExp
Fixture.givenProjectNameIs("NewProjectTest");
Fixture.whenNewProjectIsSelected();
Fixture.thenProjectIsAddedToProjectExplorer();

}

@Test
Expand Down Expand Up @@ -270,7 +269,7 @@ private static void whenProjectIsBuiltUsingContextMenu() throws IOException

private static void whenInstallNewComponentUsingContextMenu() throws IOException
{
ProjectTestOperations.openProjectNewComponentUsingContextMenu(projectName, bot);
ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Install New Component");
bot.editorByTitle(projectName).show();
bot.button("Install").click();
ProjectTestOperations.waitForProjectNewComponentInstalled(bot);
Expand Down Expand Up @@ -335,13 +334,10 @@ private static void thenFileContentsMatchDefaultFile(String path, String fileNam
}
}

private static void thenConsoleShowsBuildSuccessful()
private static void thenConsoleShowsBuildSuccessful() throws IOException
{
SWTBotView consoleView = ProjectTestOperations.viewConsole("CDT Build Console", bot);
consoleView.show();
consoleView.setFocus();
String consoleTextString = consoleView.bot().styledText().getText();
assertTrue(consoleTextString.contains("Build complete (0 errors"));
ProjectTestOperations.findInConsole(bot, "CDT Build Console [" + Fixture.projectName + "]",
"Build complete (0 errors");
}

private static void cleanTestEnv()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;

import com.espressif.idf.core.util.IDFUtil;
import com.espressif.idf.ui.test.common.configs.DefaultPropertyFetcher;
import com.espressif.idf.ui.test.common.utility.TestWidgetWaitUtility;

Expand Down Expand Up @@ -47,15 +45,6 @@ public static void setupEspressifEnv(SWTWorkbenchBot bot) throws Exception
{
prefrencesShell.bot().checkBox("Refresh using native hooks or polling").click();
}

prefrencesShell.bot().tree().getTreeItem("C/C++").select();
prefrencesShell.bot().tree().getTreeItem("C/C++").expand();
prefrencesShell.bot().tree().getTreeItem("C/C++").getNode("Indexer").select();
if (prefrencesShell.bot().checkBox("Enable indexer").isChecked())
{
prefrencesShell.bot().checkBox("Enable indexer").click();
}

prefrencesShell.bot().button("Apply and Close").click();

bot.toolbarButtonWithTooltip("Select and deselect filters to apply to the content in the tree").click();
Expand Down Expand Up @@ -88,6 +77,8 @@ public static void setupEspressifEnv(SWTWorkbenchBot bot) throws Exception
consoleView.show();
consoleView.setFocus();
TestWidgetWaitUtility.waitUntilViewContains(bot, "Tools Activated", consoleView, 99000000);
bot.cTabItem("ESP-IDF Manager").activate();
bot.cTabItem("ESP-IDF Manager").close();
SETUP = true;
}

Expand Down
Loading