KINTO Tech Blog
AutomationTesting

Dark Mode Automation Testing with Appium

Cover Image for Dark Mode Automation Testing with Appium

Introduction

My name is PannNuWai and I work in the Global Development Group at KINTO Technologies. In Global Development Group test automation team, I build and maintain test automation environments for the product development teams, and write test scripts with the product test team.
In my previous company, I was involved in testing, but after joining KINTO Technologies, I had my first experience with automation testing using Appium, which provided me with valuable learning opportunities.
I didn’t have any experience in Appium, so I had to start studying from scratch. However, I am now capable of handling everything from initial configuration to designing server architecture.
In this automation testing role, I primarily focused on testing smartphone apps and will outline the issues I resolved during the process.
In this article, I would like to talk about how to switch to dark mode using Appium version 1.22.3 for automation testing.

What is automation testing?

Software testing is the process of identifying issues in software to ensure that defective products are not released.
In this article, 'automation testing' refers to the use of tools that support and automate the software testing process.

Benefits of automation testing [1]

  • Early fault detection
  • Improve quality while keeping costs down
  • Tests can be performed even with a lack of human resources
  • Tests can be performed more quickly
  • Human error can be eliminated
  • Tests can be performed outside of business hours

What is Appium?

It is an open source tool for testing native, web views, and hybrid apps on iOS, Android, and desktop platforms. [2]

Appium supports Java, PHP, and Python programming languages, so it is an automation testing tool that testers can easily use while choosing their preferred language.
There are three components:

  • Appium Client
  • Appium Server
  • End Device
    in the architecture of Appium.
    The mobile device and app details are set up in the Appium Client.
    The Appium Server uses Node.js language to connect the simulator (iOS) or emulator (Android) while launching the json file.
    Finally, the end device is managed through the Appium server that has been launched.

What is Appium Inspector?

Appium Inspector is a standard procedure for uniquely identifying the UI elements of a mobile app. It works on both actual devices or simulators (iOS) or emulators (Android).
Note - the Appium Inspector tool is specifically designed to retrieve only native mobile application attributes, so it does not support finding locators in a web browser (Chrome).
The Appium desktop application is a combination of the Appium server itself and the Element inspector, designed to detect all visible elements of mobile applications while developing test scripts. [3]

What is Dark Mode?

Dark mode is a display setting for the user interface of smartphones, laptops, etc.
Instead of displaying dark text (dark mode) on a bright screen, light text (light mode) is displayed on a black screen.
In addition to the existing dark mode feature on both Android and iOS phones, we often use the dark mode feature in our apps. When testing mobile app automation, testing the dark mode feature was also a key checking point. So, I would like to talk about the dark mode of mobile apps using Appium.

Problem

There is a problem when using Appium to test dark mode. For example, when testing the login screen to see if the characters of username and password are displayed, the Appium inspector retrieves the location of the element for username and password. Normally, you only need to check that the element is displayed as follows.

AssertTrue(driver.findElementByXPath("USER_NAME").isDisplayed());
AssertTrue(driver.findElementByXPath("PASSWORD").isDisplayed());

However, in dark mode, it is not enough to just retrieve the location of the element and check its display. Checking that the screen has changed to black is an important part of dark mode. You need to check the hexadecimal values for the black and white colors.

Test Method

Now, let’s actually write the source code of the dark mode test case using Appium.

changeToDarkTheme

Step 1

Retrieve the location (ElementId) of the element from the Appium inspector.

Step 2

Use assertElementColorMode(MobileElement elementId, ColorMode colorMode) to confirm if light mode is the Default setting.

Step 3

Press the dark mode button.

Step 4

Use assertElementColorMode(MobileElement elementId, ColorMode colorMode) to confirm if the Display setting changes to dark mode.

public class DisplayChangePage extends Base {
    public static final String THEME_CELL_ID = "id/theme_parent";
    @Test(groups = "DisplayChangePage", dependsOnGroups = "Setting")
    public void changeToDarkTheme() {
        driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
        MobileElement themeCell = getDriver().findElementById(THEME_CELL_ID);
        assertElementColorMode(themeCell, ColorMode.LIGHT);
        themeCell.click();
        driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
        tapElement(
                findElementByTextContains(ViewType.CHECKED_TEXT, resourceText("darkTheme"))
        );
        themeCell = getDriver().findElementById(THEME_CELL_ID);
        assertElementColorMode(themeCell, ColorMode.DARK);
    }
}

assertElementColorMode

Set the ElementId where the Theme cell is located and the ColorMode you want to change as parameters.

Step 1

Retrieve evidence of the Element where the Theme cell is located. Use getElementBufferedImage(MobileElement element) to save the evidence as an image file.

Step 2

Check that the saved image file does not become null.

Step 3

Get the color from the (x = 10, y = 10) image file point and check the color of the dark mode you want to change.

public interface AppiumHelpersInterface extends FindElementsInterface {
    AppiumDriver<MobileElement> getDriver();
    Device getDevice();
    /**
     * Get buffered image of mobile element
     *
     * @param element Mobile element
     * @return Buffered image
     */
    default BufferedImage getElementBufferedImage(MobileElement element) {
        File image = element.getScreenshotAs(OutputType.FILE);
        try {
            return ImageIO.read(image);
        } catch (IOException e) {
            return null;
        }
    }
    /**
     * Assert element's color mode
     *
     * @param element Mobile Element
     * @param mode    Color mode
     */
    default void assertElementColorMode(MobileElement element, ColorMode mode) {
        BufferedImage image = getElementBufferedImage(element);
        Assert.assertNotNull(image);
        Assert.assertTrue(Utils.getColorString(image, 10, 10).matches(mode.cellRegex()));
    }
}

getColorString

Change the color of x-point and y-point of the acquired image to hexadecimal and return the array.

    /**
     * Get color string from image at point x and y
     *
     * @param image BufferedImage
     * @param x     int
     * @param y     int
     * @return Hexadecimal Color String
     */
    public static String getColorString(BufferedImage image, int x, int y) {
        int rgba = image.getRGB(x, y);
        int[] rgb = new int[]{
                (rgba >> 16) & 0xff,
                (rgba >> 8) & 0xff,
                (rgba) & 0xff
        };
        return String.format("%02x%02x%02x", rgb[0], rgb[1], rgb[2]);
    }

cellRegex

Determine the values for dark and light modes.

public enum ColorMode {
    LIGHT,
    DARK;
    public String cellRegex() {
        // 22222 - lighter black
        if (this == DARK) return "2[(0-9|a-f)]2[(0-9|a-f)]2[(0-9|a-f)]";
        // ffffff
        return "f[(0-9|a-f)]f[(0-9|a-f)]f[(0-9|a-f)]";
    }
}
public interface ColorModeInterface {
    String darkModeScript();
    Map<String, Object> darkModeSettings();
    Map<String, Object> lightModeSettings();
    default void configureDarkMode(ColorMode mode) {
        getDriver().executeScript(darkModeScript(), mode == ColorMode.DARK ? darkModeSettings() : lightModeSettings());
    }
}

Caution

This case involves using Appium, so only the native app's dark mode feature can be utilized.

Summary

In this article, I have explained how to switch to dark mode.
It can be used on both iOS (version 13 and up) and Android (version 5.0 and up) for dark mode automation testing.
This time, I tested the Native App's dark mode feature, but I would also like to explore testing the Web App's dark mode feature in the future
Since December, the number of members on the test automation team in Global Development has increased. In the future, I hope to collaborate with team members on automation testing using not only Appium but also other tools like Katalon.

Reference

脚注
  1. https://products.sint.co.jp/obpm/blog/test_automation ↩︎

  2. https://appium.io ↩︎

  3. https://www.kobiton.com/book/chapter-5-the-appium-inspector-2 ↩︎

Facebook

関連記事 | Related Posts

We are hiring!

【iOSエンジニア】モバイルアプリ開発G/東京

モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。

【iOSエンジニア】モバイルアプリ開発G/大阪

モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。