Skip to content
Open
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
125 changes: 60 additions & 65 deletions app/src/androidTest/java/fr/free/nrw/commons/WelcomeActivityTest.kt
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
package fr.free.nrw.commons

import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule
import androidx.test.uiautomator.UiDevice
import androidx.viewpager.widget.ViewPager
import fr.free.nrw.commons.utils.ConfigUtils
import org.hamcrest.core.IsNot.not
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.CoreMatchers.equalTo

@LargeTest
@RunWith(AndroidJUnit4::class)
class WelcomeActivityTest {

@get:Rule
var activityRule: ActivityTestRule<*> = ActivityTestRule(WelcomeActivity::class.java)
val composeTestRule = createAndroidComposeRule<WelcomeActivity>()

private val device: UiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

Expand All @@ -37,97 +32,97 @@ class WelcomeActivityTest {
@Test
fun ifBetaShowsSkipButton() {
if (ConfigUtils.isBetaFlavour) {
onView(withId(R.id.button_ok))
.perform(ViewActions.click())
onView(withId(R.id.finishTutorialButton))
.check(matches(isDisplayed()))
composeTestRule.onNodeWithText("OK").performClick()
composeTestRule.onNodeWithText("Skip Tutorial").assertIsDisplayed()
}
}

@Test
fun ifProdHidesSkipButton() {
if (!ConfigUtils.isBetaFlavour) {
onView(withId(R.id.button_ok))
.perform(ViewActions.click())
onView(withId(R.id.finishTutorialButton))
.check(matches(not(isDisplayed())))
composeTestRule.onNodeWithText("Skip Tutorial").assertDoesNotExist()
}
}

@Test
fun testBetaSkipButton() {
if (ConfigUtils.isBetaFlavour) {
onView(withId(R.id.button_ok))
.perform(ViewActions.click())
onView(withId(R.id.finishTutorialButton))
.perform(ViewActions.click())
assertThat(activityRule.activity.isDestroyed, equalTo(true))
composeTestRule.onNodeWithText("OK").performClick()
composeTestRule.onNodeWithText("Skip Tutorial").performClick()
composeTestRule.waitForIdle()
assertThat(composeTestRule.activity.isDestroyed, equalTo(true))
}
}

@Test
fun testSwipingOnce() {
onView(withId(R.id.button_ok))
.perform(ViewActions.click())
onView(withId(R.id.welcomePager))
.perform(ViewActions.swipeLeft())
if (ConfigUtils.isBetaFlavour) {
composeTestRule.onNodeWithText("OK").performClick()
}

composeTestRule.onRoot().performTouchInput { swipeLeft() }
assertThat(true, equalTo(true))
onView(withId(R.id.welcomePager))
.perform(ViewActions.swipeRight())

composeTestRule.onRoot().performTouchInput { swipeRight() }
assertThat(true, equalTo(true))
}

@Test
fun testSwipingWholeTutorial() {
onView(withId(R.id.button_ok))
.perform(ViewActions.click())
onView(withId(R.id.welcomePager))
.perform(ViewActions.swipeLeft())
.perform(ViewActions.swipeLeft())
.perform(ViewActions.swipeLeft())
.perform(ViewActions.swipeLeft())
if (ConfigUtils.isBetaFlavour) {
composeTestRule.onNodeWithText("OK").performClick()
}

repeat(4) {
composeTestRule.onRoot().performTouchInput { swipeLeft() }
}
assertThat(true, equalTo(true))
onView(withId(R.id.welcomePager))
.perform(ViewActions.swipeRight())
.perform(ViewActions.swipeRight())
.perform(ViewActions.swipeRight())
.perform(ViewActions.swipeRight())

repeat(4) {
composeTestRule.onRoot().performTouchInput { swipeRight() }
}
assertThat(true, equalTo(true))
}

@Test
fun swipeBeyondBounds() {
val viewPager = activityRule.activity.findViewById<ViewPager>(R.id.welcomePager)

viewPager.adapter?.let {
if (viewPager.currentItem == 3) {
onView(withId(R.id.welcomePager))
.perform(ViewActions.swipeLeft())
assertThat(true, equalTo(true))
onView(withId(R.id.welcomePager))
.perform(ViewActions.swipeRight())
assertThat(true, equalTo(true))
}
if (ConfigUtils.isBetaFlavour) {
composeTestRule.onNodeWithText("OK").performClick()
}

repeat(4) {
composeTestRule.onRoot().performTouchInput { swipeLeft() }
}

composeTestRule.onRoot().performTouchInput { swipeLeft() }
assertThat(true, equalTo(true))

composeTestRule.onRoot().performTouchInput { swipeRight() }
assertThat(true, equalTo(true))
}

@Test
fun swipeTillLastAndFinish() {
val viewPager = activityRule.activity.findViewById<ViewPager>(R.id.welcomePager)

viewPager.adapter?.let {
if (viewPager.currentItem == 3) {
onView(withId(R.id.button_ok))
.perform(ViewActions.click())
onView(withId(R.id.finishTutorialButton))
.perform(ViewActions.click())
assertThat(activityRule.activity.isDestroyed, equalTo(true))
}
if (ConfigUtils.isBetaFlavour) {
composeTestRule.onNodeWithText("OK").performClick()
}

repeat(4) {
composeTestRule.onRoot().performTouchInput { swipeLeft() }
}

composeTestRule.onNodeWithText("YES!").performClick()

composeTestRule.waitForIdle()
assertThat(composeTestRule.activity.isDestroyed, equalTo(true))
}

@Test
fun orientationChange() {
UITestHelper.changeOrientation(activityRule)
device.setOrientationLeft()
composeTestRule.waitForIdle()

device.setOrientationNatural()
composeTestRule.waitForIdle()
}
}
}
56 changes: 15 additions & 41 deletions app/src/main/java/fr/free/nrw/commons/WelcomeActivity.kt
Original file line number Diff line number Diff line change
@@ -1,53 +1,31 @@
package fr.free.nrw.commons

import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.View
import fr.free.nrw.commons.databinding.ActivityWelcomeBinding
import fr.free.nrw.commons.databinding.PopupForCopyrightBinding
import fr.free.nrw.commons.quiz.QuizActivity
import fr.free.nrw.commons.theme.BaseActivity
import fr.free.nrw.commons.utils.applyEdgeToEdgeAllInsets
import androidx.activity.compose.setContent
import androidx.compose.material3.MaterialTheme
import fr.free.nrw.commons.utils.ConfigUtils.isBetaFlavour

class WelcomeActivity : BaseActivity() {
private var binding: ActivityWelcomeBinding? = null
private var isQuiz = false

/**
* Initialises exiting fields and dependencies
*
* @param savedInstanceState WelcomeActivity bundled data
*/
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityWelcomeBinding.inflate(layoutInflater)
applyEdgeToEdgeAllInsets(binding!!.welcomePager.rootView)
setContentView(binding!!.root)

isQuiz = intent?.extras?.getBoolean("isQuiz", false) ?: false

// Enable skip button if beta flavor
if (isBetaFlavour) {
binding!!.finishTutorialButton.visibility = View.VISIBLE

val copyrightBinding = PopupForCopyrightBinding.inflate(layoutInflater)

val dialog = AlertDialog.Builder(this)
.setView(copyrightBinding.root)
.setCancelable(false)
.create()
dialog.show()

copyrightBinding.buttonOk.setOnClickListener { v: View? -> dialog.dismiss() }
setContent {
MaterialTheme {
WelcomeScreen(
isBetaFlavour = isBetaFlavour,
pageCount = 5,
onSkipClicked = { finishTutorial() },
onBackPressedAtStart = { handleBackAtStart() }
)
}
}
Comment thread
Roniscend marked this conversation as resolved.

val adapter = WelcomePagerAdapter()
binding!!.welcomePager.adapter = adapter
binding!!.welcomePagerIndicator.setViewPager(binding!!.welcomePager)
binding!!.finishTutorialButton.setOnClickListener { v: View? -> finishTutorial() }
}

public override fun onDestroy() {
Expand All @@ -57,15 +35,11 @@ class WelcomeActivity : BaseActivity() {
super.onDestroy()
}

override fun onBackPressed() {
if (binding!!.welcomePager.currentItem != 0) {
binding!!.welcomePager.setCurrentItem(binding!!.welcomePager.currentItem - 1, true)
private fun handleBackAtStart() {
if (defaultKvStore.getBoolean("firstrun", true)) {
finishAffinity()
} else {
if (defaultKvStore.getBoolean("firstrun", true)) {
finishAffinity()
} else {
super.onBackPressed()
}
finish()
}
}

Expand Down
92 changes: 92 additions & 0 deletions app/src/main/java/fr/free/nrw/commons/WelcomeDoUploadPage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package fr.free.nrw.commons

import android.content.res.Configuration
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import fr.free.nrw.commons.R

@Composable
fun WelcomeDoUploadPage() {
val configuration = LocalConfiguration.current
val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = dimensionResource(id = R.dimen.huge_gap))
.verticalScroll(rememberScrollState())
.padding(top = 90.dp, bottom = 45.dp)
.safeDrawingPadding(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {

Image(
painter = painterResource(id = R.drawable.welcome_do_upload),
contentDescription = stringResource(id = R.string.welcome_do_upload_content_description),
modifier = Modifier
.size(if (isLandscape) 200.dp else 300.dp),
contentScale = ContentScale.Fit
)

Spacer(modifier = Modifier.height(24.dp))

Text(
text = stringResource(id = R.string.tutorial_2_text),
color = Color.White,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.titleMedium,
)

Spacer(modifier = Modifier.height(dimensionResource(id = R.dimen.standard_gap)))

Column(
verticalArrangement = Arrangement.spacedBy(12.dp),
modifier = Modifier.fillMaxWidth()
) {
BulletText(textRes = R.string.tutorial_2_subtext_1)
BulletText(textRes = R.string.tutorial_2_subtext_2)
BulletText(textRes = R.string.tutorial_2_subtext_3)
}
}
}

@Composable
fun BulletText(textRes: Int) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.Top
) {
Box(
modifier = Modifier
.padding(top = 8.dp, end = 8.dp)
.size(6.dp)
.clip(CircleShape)
.background(Color.White)
)
Text(
text = stringResource(id = textRes),
color = Color.White,
style = MaterialTheme.typography.bodyMedium
)
}
}
Loading
Loading