From 1010d1f09a47be9b2763f52748e305579c80c98c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20Gl=C3=B6ckner?= <axel.glockner00@gmail.com> Date: Tue, 5 Dec 2023 15:12:58 +0100 Subject: [PATCH] ui-testing --- .../androidTestResultsUserPreferences.xml | 35 ++++++++ .../app/build.gradle.kts | 4 +- .../ExampleInstrumentedTest.java | 84 +++++++++++++++++-- .../passwordstrenghtmeter/Password.java | 18 ++++ .../PasswordStrengthMeter.java | 35 ++++++-- .../passwordstrenghtmeter/StrengthBar.java | 47 +++++++++++ 6 files changed, 208 insertions(+), 15 deletions(-) create mode 100644 projects/PasswordStrenghtMeter/.idea/androidTestResultsUserPreferences.xml diff --git a/projects/PasswordStrenghtMeter/.idea/androidTestResultsUserPreferences.xml b/projects/PasswordStrenghtMeter/.idea/androidTestResultsUserPreferences.xml new file mode 100644 index 0000000..73dfedf --- /dev/null +++ b/projects/PasswordStrenghtMeter/.idea/androidTestResultsUserPreferences.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="AndroidTestResultsUserPreferences"> + <option name="androidTestResultsTableState"> + <map> + <entry key="-1360427803"> + <value> + <AndroidTestResultsTableState> + <option name="preferredColumnWidths"> + <map> + <entry key="Duration" value="90" /> + <entry key="Pixel_6_API_34" value="120" /> + <entry key="Tests" value="360" /> + </map> + </option> + </AndroidTestResultsTableState> + </value> + </entry> + <entry key="-664877063"> + <value> + <AndroidTestResultsTableState> + <option name="preferredColumnWidths"> + <map> + <entry key="Duration" value="90" /> + <entry key="Pixel_6_API_34" value="120" /> + <entry key="Tests" value="360" /> + </map> + </option> + </AndroidTestResultsTableState> + </value> + </entry> + </map> + </option> + </component> +</project> \ No newline at end of file diff --git a/projects/PasswordStrenghtMeter/app/build.gradle.kts b/projects/PasswordStrenghtMeter/app/build.gradle.kts index d8ce6c3..e1270e0 100644 --- a/projects/PasswordStrenghtMeter/app/build.gradle.kts +++ b/projects/PasswordStrenghtMeter/app/build.gradle.kts @@ -12,7 +12,6 @@ android { targetSdk = 34 versionCode = 1 versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -29,11 +28,12 @@ android { } dependencies { - implementation("androidx.appcompat:appcompat:1.6.1") implementation("com.google.android.material:material:1.10.0") implementation("androidx.constraintlayout:constraintlayout:2.1.4") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation("androidx.test:rules:1.5.0") + androidTestImplementation("androidx.test:runner:1.5.2") } \ No newline at end of file diff --git a/projects/PasswordStrenghtMeter/app/src/androidTest/java/com/example/passwordstrenghtmeter/ExampleInstrumentedTest.java b/projects/PasswordStrenghtMeter/app/src/androidTest/java/com/example/passwordstrenghtmeter/ExampleInstrumentedTest.java index 8158124..e8fa614 100644 --- a/projects/PasswordStrenghtMeter/app/src/androidTest/java/com/example/passwordstrenghtmeter/ExampleInstrumentedTest.java +++ b/projects/PasswordStrenghtMeter/app/src/androidTest/java/com/example/passwordstrenghtmeter/ExampleInstrumentedTest.java @@ -1,26 +1,96 @@ package com.example.passwordstrenghtmeter; - +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.typeText; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.withId; import android.content.Context; - +import androidx.test.ext.junit.rules.ActivityScenarioRule; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.ext.junit.runners.AndroidJUnit4; - +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; - import static org.junit.Assert.*; /** - * Instrumented test, which will execute on an Android device. + * Instrumented test class for testing the password strength meter. * - * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + * This class contains a set of tests to ensure the proper functionality of the password strength meter + * in the context of an Android device. */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { + + /** + * Ensures that we are running main activity. + */ + @Rule + public ActivityScenarioRule<MainActivity> activityRule = + new ActivityScenarioRule<>(MainActivity.class); + + /** + * Verify that the application's context is correct. + */ @Test public void useAppContext() { // Context of the app under test. Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); assertEquals("com.example.passwordstrenghtmeter", appContext.getPackageName()); } -} \ No newline at end of file + + /** + * Test for a weak password. + * + * This test enters a weak password and checks if the strength bar is displayed and if the + * password strength is correctly identified as "Weak". + */ + @Test + public void weakPasswordTest() { + onView(withId(Password.passwordId)).perform(typeText("password")); + onView(withId(StrengthBar.strengthBarId)).check(matches(isDisplayed())); + assertEquals("Weak", getPasswordStrength()); + } + + /** + * Test for a medium-strength password. + * + * This test enters a medium-strength password and checks if the strength bar is displayed and + * if the password strength is correctly identified as "Medium". + */ + @Test + public void mediumPasswordTest() { + onView(withId(Password.passwordId)).perform(typeText("Password")); + onView(withId(StrengthBar.strengthBarId)).check(matches(isDisplayed())); + assertEquals("Medium", getPasswordStrength()); + } + + /** + * Test for a strong password. + * + * This test enters a strong password and checks if the strength bar is displayed and if the + * password strength is correctly identified as "Strong". + */ + @Test + public void strongPasswordTest() { + onView(withId(Password.passwordId)).perform(typeText("Password@")); + onView(withId(StrengthBar.strengthBarId)).check(matches(isDisplayed())); + assertEquals("Strong", getPasswordStrength()); + } + + /** + * Helper method to get the password strength. + * + * This method retrieves the password strength from the StrengthBar and returns it as a string. + * + * @return The password strength ("Weak", "Medium", or "Strong"). + */ + private String getPasswordStrength() { + final String[] passwordStrength = new String[1]; + activityRule.getScenario().onActivity(activity -> { + StrengthBar strengthBar = activity.findViewById(StrengthBar.strengthBarId); + passwordStrength[0] = strengthBar.getPasswordStrenght(); + }); + return passwordStrength[0]; + } +} diff --git a/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/Password.java b/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/Password.java index a89673a..cca8592 100644 --- a/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/Password.java +++ b/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/Password.java @@ -1,13 +1,17 @@ package com.example.passwordstrenghtmeter; import android.content.Context; +import android.os.Build; import android.text.InputType; import android.util.AttributeSet; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.view.ViewCompat; public class Password extends androidx.appcompat.widget.AppCompatEditText { private View passwordView; + public static int passwordId; // EditText id. + public Password(@NonNull Context context) { super(context); init(); @@ -28,6 +32,20 @@ public class Password extends androidx.appcompat.widget.AppCompatEditText { setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD ); setGravity(android.view.Gravity.CENTER_VERTICAL | android.view.Gravity.CENTER_HORIZONTAL); this.passwordView = this; + passwordId = generateID(); + setId(passwordId); + } + + /** + * Generate a unique id + * @return id + */ + private int generateID(){ + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + return ViewCompat.generateViewId(); + } else { + return View.generateViewId(); + } } public void setView(View view){ diff --git a/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/PasswordStrengthMeter.java b/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/PasswordStrengthMeter.java index 5c2995b..493788d 100644 --- a/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/PasswordStrengthMeter.java +++ b/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/PasswordStrengthMeter.java @@ -4,6 +4,7 @@ import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.view.View; +import android.widget.Button; import android.widget.LinearLayout; import androidx.annotation.Nullable; @@ -12,6 +13,12 @@ public class PasswordStrengthMeter extends LinearLayout { private Password password; private StrengthBar strengthBar; private String passwordData; + + private String text; + + private Button button; + + private int passwordId; public PasswordStrengthMeter(Context context) { super(context); } @@ -39,13 +46,30 @@ public class PasswordStrengthMeter extends LinearLayout { password = new Password(getContext()); strengthBar = new StrengthBar(getContext()); strengthValidator = new DefaultValidator(); + button = new Button(getContext()); password.addTextChangedListener(getTextWatcher()); + button.setText("Register"); strengthBar.setErrorMessage(strengthValidator.ErrorMessage()); + button.setOnClickListener(v -> onButtonClicked()); addView(password); addView(strengthBar); + addView(button); addView(strengthBar.getErrorMessageView()); } + /** + * If the password is strong, and the button is clicked we save the password. + */ + private void onButtonClicked(){ + if(text!=null) { + if (strengthValidator.ValidateLength(text) + && strengthValidator.ValidateSpecialCharacters(text) + && strengthValidator.ValidateCapLetters(text)) { + setPasswordData(text); + } + } + + } /** * A text watcher to dynamically validate the password. * @return TextWatcher @@ -60,18 +84,13 @@ public class PasswordStrengthMeter extends LinearLayout { @Override public void afterTextChanged(Editable s) { - final String text = s.toString(); + text = s.toString(); if(text.isEmpty()){ strengthBar.hideErrorMessage(); } strengthBar.updateStrengthNew(strengthValidator.ValidateLength(text), strengthValidator.ValidateSpecialCharacters(text), strengthValidator.ValidateCapLetters(text)); - if(strengthValidator.ValidateLength(text) - && strengthValidator.ValidateSpecialCharacters(text) - && strengthValidator.ValidateCapLetters(text)){ - setPasswordData(text); - } } }; } @@ -120,4 +139,8 @@ public class PasswordStrengthMeter extends LinearLayout { public String getPasswordData(){ return this.passwordData; } + + public int getPasswordId(){ + return password.getId(); + } } diff --git a/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/StrengthBar.java b/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/StrengthBar.java index 993184e..1ec30d0 100644 --- a/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/StrengthBar.java +++ b/projects/PasswordStrenghtMeter/app/src/main/java/com/example/passwordstrenghtmeter/StrengthBar.java @@ -2,10 +2,15 @@ package com.example.passwordstrenghtmeter; import android.content.Context; import android.graphics.Color; import android.graphics.PorterDuff; +import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; + +import androidx.core.view.ViewCompat; + public class StrengthBar extends ProgressBar { private static final int defaultColor = Color.TRANSPARENT; // constant for transparent color. private static final int alpha = 255; // constant for 100% opacity. @@ -14,6 +19,9 @@ public class StrengthBar extends ProgressBar { private int mediumColor; private int strongColor; private View progressBarView; + public static int strengthBarId; + + private int strength; public StrengthBar(Context context) { super(context, null, android.R.attr.progressBarStyleHorizontal); @@ -32,6 +40,18 @@ public class StrengthBar extends ProgressBar { init(); } + /** + * Generate a unique id + * @return id + */ + private int generateID(){ + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + return ViewCompat.generateViewId(); + } else { + return View.generateViewId(); + } + } + /** * Initialize colors and error messages. */ @@ -44,6 +64,9 @@ public class StrengthBar extends ProgressBar { errorMessage.setVisibility(View.GONE); errorMessage.setGravity(android.view.Gravity.CENTER_VERTICAL | android.view.Gravity.CENTER_HORIZONTAL); this.progressBarView = this; + strengthBarId = generateID(); + setId(strengthBarId); + } protected void hideErrorMessage() { @@ -70,6 +93,7 @@ public class StrengthBar extends ProgressBar { }if(capLet){ trueCount++; } + setStrength(trueCount); if(trueCount==0){ setProgressbarColor(defaultColor); showErrorMessage(); @@ -130,4 +154,27 @@ public class StrengthBar extends ProgressBar { protected void setErrorMessage(String message){ errorMessage.setText(message); } + + public int getStrength() { + return strength; + } + public void setStrength(int strength) { + this.strength = strength; + } + + /** + * For confirming a test. + * @return + */ + public String getPasswordStrenght(){ + if(this.strength==1){ + return "Weak"; + }else if(this.strength==2){ + return "Medium"; + }else if (this.strength==3){ + return "Strong"; + }else{ + return null; + } + } } -- GitLab