Create a React-Native App to Display a Web App and Use SafeAreaView

Last week I needed to create a React Native app to display a web app in a web browser, this is a temporary solution as I work on a real native app. I used create-react-native-app and Expo, which I would highly recommend if you’re creating a basic app. I did end up having to eject, and at that point I just abandoned Expo altogether.

Using create-react-native-app was super nice, I was able to create a React Native app in minutes, no guessing or going through documentation to see what files or dependencies I need to get started.

I hadn’t heard of Expo, but I’ll definitely be using React Native for all of my mobile apps now, just because Expo is so helpful! The ability to see changes in real time on physical devices and emulators, plus the ease of building .apk and .ipa files, plus so many more features I haven’t used yet, makes it amazing!

The most difficult part was getting SafeAreaView to work the way I wanted. I used SafeAreaView to take care of the formatting for the iPhone X type devices, since the Home bar/not button/thing was in the way of the web browser window.

My issue was that I couldn’t get the status bar to be orange, and the chin area to stay white, it was also orange. Then I realized that the way I set this up originally had created a small chin at the bottom of Android and standard iPhone devices.

After enough messing around, I finally came up with a solution. It formatted the WebView perfectly, plus had the colors I wanted in the right areas.

This is what my code looks like:



export default class App extends React.Component 
{

  render() 
  {

    return (

    <React.Fragment>
      
<SafeAreaView style={ styles.statusBar } />
      
<SafeAreaView style={ styles.webView }>
      
 <WebView
source={{ uri: 'https://test-webapp.com' }}/>
      
</SafeAreaView>

    </React.Fragment>
);

  }

}

const styles = StyleSheet.create({
  
statusBar: {
flex: 0,
backgroundColor: '#ff9136'
},
  
webView: {
flex: 1,
backgroundColor: '#fff',
paddingTop: 30
}

});

Selenium WebDriver Web App Sign Up Test

Lately I’ve been having fun with the Selenium WebDriver to test a Web App! It’s super fun, and if you haven’t used Selenium before, I highly recommend it!

I’m writing all of my tests in C#, and it was really easy to get started thanks to Selenium’s documentation and some nice write-ups from Microsoft.

The most fun test so far has been the Sign Up test. Obviously I want to make sure that the process to Sign Up for a new account doesn’t break, so I created a test for it.

The sign up process I’m testing, however, requires that you provide a verification code sent  to your email. I started looking into how this could be done. Maybe creating a Selenium method to sign into a Gmail account, or use the Zapier email parser?

I landed on using Gmail’s API, and it works quite well! Thankfully Google’s documentation is fantastic and I was able to figure it out relatively quickly. The quickstart was extremely helpful, I would definitely recommend starting there.

My Sign Up test uses a .runsettings file that I set up in an Azure DevOps Release Pipeline. That way I can create a unique email per release. It looks something like [email protected] I didn’t include the setup code for the Gmail API below, but you can find it in their quickstart.

The code for retrieving the verification was fairly simple.

Let me know if I can do anything better!

List result = new List(); // Create a list

UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List("me"); // Define the request

request.Q = "to:" + email; // Define our filter to search for the email address we specify

do
{
  try
  {
    ListMessagesResponse response = request.Execute(); // Execute the request
    result.AddRange(response.Messages); // Add the emails we find to the list
    request.PageToken = response.NextPageToken; // Look for more results
  }
  catch (Exception e)
  {
    Trace.Write("An error occurred: " + e.Message);
  }
} while (!String.IsNullOrEmpty(request.PageToken)); // Stop looking when there are no more results

var id = result.Select(x = x.Id).ToArray(); // Get email id from our results, should only be one email to get id out of

try
{
  var message = service.Users.Messages.Get("me", id[0]).Execute(); // Get the email using the email id
  string snippet = message.Snippet; // Retrieve the snippet from the email
  string numbers = Regex.Replace(snippet, "[^0-9]+", string.Empty); // Get numbers out of snippet
  string code = numbers.Substring(numbers.Length - 6, 6); // Our code is six digits and always at the end, get the last six numbers
  return code; // Return our verification code
}
catch (Exception e)
{
  Trace.Write("An error occurred: " + e.Message);
}

return null; // If no verification code was found, return null

Creating a Unique Email Address to Use in Selenium tests from Release Pipeline

Recently I needed to come up with a way to create a unique email address each time I run my Selenium tests. This is because I’m running Sign Up tests to ensure the Sign Up process works properly.

Since I’m using Azure DevOps Release Pipeline to run my tests, I thought I might be able to use a custom variable to increment an email address. Then I can pass the variable to my tests using .runsettings. I’m using Gmail for my testing, so creating a working, custom email address is fairly easy. I can just utilize their [email protected] functionality.

For those of you who aren’t familiar with + functionality within Gmail, you can actually add a + to the end of your email address. This way the email address looks different, but it actually goes to the same mailbox. For example, if you had an email address of [email protected], you can use [email protected] and still receive emails sent to the +whatever address.

I created a newEmailAddress variable in the Release Pipeline and just set it to some test email, the value doesn’t really matter, we’ll change it during our release.

In my Selenium code, I added three PowerShell scripts, one for each of my stages. The scripts look like this:

$release = $env:RELEASE_RELEASENAME; 
# Get the current release name from the Release Pipeline

$email = "tester+" + $release + "[email protected]"; 
# Create the email address

Write-Host "##vso[task.setvariable variable=newEmailAddress]$email"; 
# Set the Release Pipeline variable to the email address we want to use.

When the Release Pipeline runs, the PowerShell script runs as a task first. Now that the newEmailAddress variable is set to the email address we want to use, we can use this custom variable in our VS Test task. In the VS Test task, we pass this variable to our tests using the override test run parameters field. My parameter looks like this:

-newEmailAddress “$(newEmailAddress)”

The -newEmailAddress corresponds to the parameter I have outline in my .runsettings file. Then the following variable is our custom variable created in the Release Pipeline.

Now we can use this custom email address in our code!

Using .runsettings to Configure Selenium Tests from Release Pipeline

I wanted to be able to tell my Selenium tests what browser to test and what resolution to use from my Azure DevOps Release Pipeline. In order to do so, I utilized a .runsettings file.

First I created a .runsettings file and placed it in my Selenium code. I created two parameters, one for testBrowser and one for windowSize, then set them to their default values.

Next I created six stages in my Release Pipeline, two for Chrome, both Desktop and mobile. Then two for Firefox and two for IE.

In order to tell my code to use the appropriate driver for each stage, I specified the .runsettings file to use in the settings file field of each VS Test task.

Then I added the correct parameter and value to their respective stage. For example, the Firefox stage for the desktop resolution has the following values in the override test run parameters field:

-testBrowser Firefox -windowSize Desktop

Now I can use these values in my test methods by creating variables and setting them to the value we passed to .runsettings.

In order to get the .runsettings values in my tests, I needed to use TestContext. The code looks like this:

namespace Tests

{

  [TestClass]
  
public class Test
  
{

    // Declare an instance of TestContext
    private static TestContext testContextInstance; 
    
    // Declare testBrowser
    
private string testBrowser; 
    
    // Declare windowSize
    
private string windowSize; 

    public Test()
    
{
    
}
    
    [TestMethod]
[TestCategory(nameof(testBrowser))]
    
public void Test_Test()

    {

      if (windowSize == "Desktop") // Determine if we are testing on desktop or mobile

      {

        // Run test using IDs, classes, XPaths that are visible in desktop resolution
      
}

      else if (windowSize == "Mobile")

      {

        // Run test using IDs, classes, XPaths that are visible in mobile resolution

      }

      else
      
{

        CustomException ex = new CustomException("windowSize in Test_Framework() not valid");

        throw ex;
      }
    
}
    
    public TestContext TestContext // Setup TestContext
    
{
      
get

      {

        return testContextInstance;
      
}

      set

      {

        testContextInstance = value;
      
}

    }
    
    [TestInitialize()]

    public void Setup_Test_Test()

    {

      testBrowser = testContextInstance.Properties["testBrowser"].ToString(); 
      // Initialize our testBrowser variable with the value from .runsettings parameter.
windowSize = testContextInstance.Properties["windowSize"].ToString(); 
      // Initialize our windowSize variable with the value from .runsettings parameter.

    }
    
    [TestCleanup()]
public void Cleanup_Test_Test()

    {
      
Config.driver.Quit(); 
      // Close the driver (it's created in my Config class)

    }
  
}

}

We’re back baby!

I went ahead and re-created my blog. This time using a fancier theme and I’ll actually be updating it! In the past few years I’ve learned a ton and have come a long way from where I started my last blog, I think that deserves a full refresh.

I worked as a Software Test Engineer, System Administrator, Service Engineer and QA Lead. My skills have really grown but I’m constantly learning and pushing myself to learn more. This blog will be updated with past things I’ve learned from various projects and personal exploration.

My future plans are to keep working towards some awesome things, while learning and growing in my free time. For the last year or so I was really into infosec, staying on top of latest vulnerabilities and testing my skills with HackTheBox (which you should totally check out if you’re interested, it’s super cool).

Currently I’ve been more interested in programming and creating applications. I have a few things I’d like to create in 2019. An app to search out the nearest good weather, a custom blog for myself, and a few other surprises. Be sure to stay up to date!