gsantner / gsantner/markor

Offer to Contribute Reproducible Test Case for Previously Reported Bug

Open
#2,584 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
6.1k
Forks
537
Avg merge
1d 18h
Merged PRs (30d)
4

Description

### ⚠️ This issue respects the following points: ⚠️

- [x] This is a **enhancement/feature request**. Not a [bug or question](https://github.com/gsantner/markor/issues/new/choose).
- [x] The topic is **not** already reported at [Issues](https://github.com/gsantner/markor/issues?q=#js-issues-search). _(I've searched it)_.
- [x] Markor **is** up to date. See [Releases](https://github.com/gsantner/markor/tags) for the latest version. Updates are available from [F-Droid](https://f-droid.org/en/packages/net.gsantner.markor/) and GitHub.
- [x] The wanted feature/enhancement is not present in the latest development version (git master). (Please [download](https://nightly.link/gsantner/markor/workflows/build-android-project/master) and try the test version of Markor, named **Marder**. Don't worry; Markor and Marder appear as completely separate applications. You can install both side-by-side, and Markor's settings are not touched. If your desired feature is present, you don't need to open this issue. The change will be part of the next Markor update.)

### Description

Hello!

I saw that the app previously had a bug (issue #1020). I created a test (based on that version of the app) to help ensuring that the issue does not happen again. In other words, the test could be used for regression testing.

Would it be helpful if I contributed this test to your codebase? I’d be happy to open a pull request for the latest version, integrating the test with your existing test infrastructure.

Please let me know if you're open to this or if there are any contribution guidelines I should follow.

Thanks for your work on this project!

### Information

You can find the script for issue #1020 below:
```

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;

import androidx.test.filters.SdkSuppress;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
import androidx.test.uiautomator.Until;

import java.util.concurrent.TimeUnit;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

/**
* Regression test for Markor (net.gsantner.markor).
* Verifies file creation flow and confirms the extension is not duplicated or corrupted.
*/
@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 18)
public class MarkorFileCreationExtensionBugTest {

private static final String PACKAGE_NAME = "net.gsantner.markor";
private static final String INSTALLER_PACKAGE = "com.android.packageinstaller";
private static final int LAUNCH_TIMEOUT = 5000;

private UiDevice mDevice;

@Before
public void startMainActivityFromHomeScreen() {
mDevice = UiDevice.getInstance(getInstrumentation());

// Go to home screen
mDevice.pressHome();

// Wait for launcher to be ready
final String launcherPackage = getLauncherPackageName();
assertThat(launcherPackage, notNullValue());
mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), LAUNCH_TIMEOUT);

// Launch Markor app
Context context = getApplicationContext();
Intent intent = context.getPackageManager()
.getLaunchIntentForPackage(PACKAGE_NAME);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
context.startActivity(intent);

// Wait for Markor UI to load
mDevice.wait(Until.hasObject(By.pkg(PACKAGE_NAME).depth(0)), LAUNCH_TIMEOUT);
}

@Test
public void testChangeText_sameActivity() {
// Tap through onboarding/tutorial screens
UiObject2 nextButton = mDevice.findObject(By.res(PACKAGE_NAME, "next"));
nextButton.click(); // page 1
nextButton.click(); // page 2

// Grant permissions
UiObject2 allowButton = mDevice.wait(Until.findObject(By.res(INSTALLER_PACKAGE, "permission_allow_button")), 3000);
allowButton.click();

// Continue tutorial
UiObject2 nextButton2 = mDevice.wait(Until.findObject(By.res(PACKAGE_NAME, "next")), 1000);
nextButton2.click(); // page 3
nextButton2.click(); // page 4
nextButton2.click(); // page 5

// Complete onboarding
UiObject2 doneButton = mDevice.findObject(By.res(PACKAGE_NAME, "done"));
doneButton.click();

UiObject2 okButton = mDevice.wait(Until.findObject(By.res("android", "button1")), 2000);
okButton.click();

// Create new file
UiObject2 addButton = mDevice.wait(Until.findObject(By.res(PACKAGE_NAME, "fab_add_new_item")), 2000);
addButton.click();

UiObject2 fileNameField = mDevice.wait(Until.findObject(By.res(PACKAGE_NAME, "new_file_dialog__name")), 2000);
fileNameField.setText("Test");

UiObject2 fileExtensionField = mDevice.wait(Until.findObject(By.res(PACKAGE_NAME, "new_file_dialog__ext")), 2000);
fileExtensionField.setText("Todo.txt");

UiObject2 confirmButton = mDevice.wait(Until.findObject(By.res("android", "button1")), 2000);
confirmButton.click();

// Navigate back to home
UiObject backButton = mDevice.findObject(new UiSelector().className("android.widget.ImageButton").instance(0));
try {
backButton.click();
} catch (UiObjectNotFoundException e) {
e.printStackTrace();
}

// Create another new file
UiObject2 addButtonAgain = mDevice.findObject(By.res(PACKAGE_NAME, "fab_add_new_item"));
addButtonAgain.click();

try {
TimeUnit.MILLISECONDS.sleep(2000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}

// === Assertion: Check that the markdown template is visible and the extension is still valid ===
UiObject2 fileTypeLabel = mDevice.findObject(By.text("Markdown"));
UiObject2 extensionField = mDevice.findObject(By.res(PACKAGE_NAME, "new_file_dialog__ext"));

assertFalse(
fileTypeLabel.getText().equals("Markdown") &&
extensionField.getText().contains(".todo.txt") // Check for extension bug or duplication
);
}

/**
* Retrieves the launcher package name (compatible across devices).
*/
private String getLauncherPackageName() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
PackageManager pm = getApplicationContext().getPackageManager();
ResolveInfo resolveInfo = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
return resolveInfo.activityInfo.packageName;
}
}

```

### Source

F-Droid

### Format / File type

Not specific

### Additional info / Log

```shell
-
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with issue #1020 and the provided MarkorFileCreationExtensionBugTest script, then inspect the existing Android test infrastructure to determine where this regression test belongs. Done means the test is adapted for the current version, integrated into the project’s test setup, and passes for the file-creation regression.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java
Domain
mobile-dev, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.