SlideShare a Scribd company logo
Made each other 

!!
How ,
and
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
Conversational
" #
User interface
The app
" #
User interface
After install
$ %
onBoarding
The app
Movie
The app
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
Appium + Appium Desktop
webdriver.io
CucumberJS
multiple-cucumber-html-report
Amsterdam 2017
Automation setup
Detox versus Appium
London 2018
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
Happy developers
Why?
Remove flakiness / inconsistent testdata problem
Test errors / delays / edge cases
Speed up manual and automated tests
Who doesn’t want to be happy? &
Happy developers
Why?
Remove flakiness / inconsistent testdata problem
Test errors / delays / edge cases
Speed up manual and automated tests
Who doesn’t want to be happy? &
Happy developers
Why?
With ng-apimock
How
Ng-apimock
Happy developers
Why?
Remove flakiness / inconsistent testdata problem
Test errors / delays / edge cases
Speed up manual and automated tests
Who doesn’t want to be happy? &
With ng-apimock
How
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
Script once
AccessibilityLabels (98%)
XPath (2%)
HyBrid solution
Testproperties
Implementation
Platform specific
Code
Testproperties
/**
* If we have a test build, add a unique test id for iOS and Android
*
* @param {string} id
*
* @return {object|*}
*/
function testProperties(id) {
if (IS_AUTOMATION_BUILD) {
if (IS_IOS) {
return {
testID: `test-${id}`,
};
}
return {
accessibilityLabel: `test-${id}`,
};
}
return null;
}
Testproperties
/**
* If we have a test build, add a unique test id for iOS and Android
*
* @param {string} id
*
* @return {object|*}
*/
function testProperties(id) {
if (IS_AUTOMATION_BUILD) {
if (IS_IOS) {
return {
testID: `test-${id}`,
};
}
return {
accessibilityLabel: `test-${id}`,
};
}
return null;
}
Implementation
import React, { Component } from 'react';
import { View } from ‘react-native';
import { testProperties } from './config/automation/TestProperties';
class MultipleChoice extends Component {
// Some code
render() {
const { options } = this.props;
return (
<View
style={styles.container}
accessibilityLabel="Wijzig uw keuze"
{…testProperties('Select menu')}
>
// The select implementation
</View>
);
}
}
Implementation
import React, { Component } from 'react';
import { View } from ‘react-native';
import { testProperties } from './config/automation/TestProperties';
class MultipleChoice extends Component {
// Some code
render() {
const { options } = this.props;
return (
<View
style={styles.container}
accessibilityLabel="Wijzig uw keuze"
{…testProperties('Select menu')}
>
// The select implementation
</View>
);
}
}
AccessiBility laBel
AccessiBility laBel
Script once
AccessibilityLabels (98%)
XPath (2%)
HyBrid solution
Testproperties
Implementation
Platform specific
Code
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
Shortcuts
Parallel execution
Animations
Optimisation
95%Behind onBoarding
So….
Shortcuts
Behind onBoarding
So….
Or
$ %
Best test feature
Or Do some
Shortcuts
$ %
Best test feature
Or Do some
'
magic?
Magic with
Shortcuts
'
magic?
Magic with
(
For 5 features
Shortcuts
Testlink screen
import TestLinkScreen from './TestLinkScreen';
/**
* Create the test link stack if it's a mocked build
*
* @return {*}
*/
function testLinkStack() {
if (MOCKED_ENVIRONMENTS.includes(ENVIRONMENT)) {
return {
[TEST_LINK_SCREEN]: {
screen: TestLinkScreen,
},
};
}
return {};
}
95%Behind onBoarding
So….
Shortcuts
Shortcuts
Parallel execution
Animations
Optimisation
Parallel execution
Not
… each scenario on each )
… all )) have the same ⚡
… all )) start with same scenario at same ⏱
… same API response on all ))
Prevent
Ng-apimock
Mockserver
Post: api/version/login
"Content-Type": "application/json",
"Accept": “application/json"
response:
{
"status": 200,
"firstName": "Wim",
"lastName": “Selles"
}
Ng-apimock
Mockserver
weBdriver.io
PUT:
headers: {
'Content-Type': ‘application/json'
},
method: 'PUT',
body: {
identifier: 'token',
scenario: 'unauthorised'
}
Ng-apimock
Mockserver
weBdriver.io
The idea
Mockserver
weBdriver.io
IDFV: 51A82F08-CCAC-410F
The idea
Mockserver
weBdriver.io
IDFV: 51A82F08-CCAC-410F
The idea
Mockserver
weBdriver.io
PUT:
headers: {
'Content-Type': ‘application/json’,
ngapimockid: '51A82F08-CCAC-410F'
},
method: 'PUT',
body: {
identifier: 'token',
scenario: 'unauthorised'
}
IDFV: 51A82F08-CCAC-410F
response:
{
"status": 401,
“message": “unauthorised"
}
The idea
Mockserver
weBdriver.io
PUT:
headers: {
'Content-Type': ‘application/json’,
ngapimockid: '51A82F08-CCAC-410F'
},
method: 'PUT',
body: {
identifier: 'token',
scenario: 'unauthorised'
}
IDFV: 51A82F08-CCAC-410F
Post: api/version/login
"Content-Type": "application/json",
"Accept": “application/json”,
ngapimockid: '51A82F08-CCAC-410F'
/**
* This is the config-file we use for calling all the API’s.
* Below you will see a part of the config to attach the headers
* to all API calls
*/
import { uniqueAutomationApiHeaderId } from './automation/TestProperties';
const apiConfig = create({
baseURL: BASE_URL,
headers: {
...API_HEADERS,
...uniqueAutomationApiHeaderId(),
},
});
Header
/**
* This is a part from our `TestProperties`-file.
*/
import { getUniqueID } from 'react-native-device-info';
/**
* If it is an automation build, then add a new header for the API calls
*
* @return {Object}
*
* For iOS it will return something like: FCDBD8EF-62FC-4ECB-B2F5-92C9E79AC7F9
* For Android it will return something like: dd96dec43fb81c97
*/
function uniqueAutomationApiHeaderId() {
if (IS_AUTOMATION_BUILD) {
return {
ngapimockid: getUniqueID(),
};
}
return {};
}
app method
Testlink screen
Testlink screen
Testlink screen
Testlink screen
/**
* Executes the api call with the provided information.
*
* @param {string} httpMethod PUT|DELETE|POST|GET
* @param {string} urlSuffix Which path to httpMethod the data to
* @param {Object} options The data that needs to be httpMethod
* @param {string} errorMessage The error that needs to be shown
*
* @return {Promise} The promise.
*
* @private
*/
function execute(httpMethod, urlSuffix, options, errorMessage) {
const data = {
headers: {
'Content-Type': 'application/json',
ngapimockid: device.uniqueID,
},
method: httpMethod,
};
if (options !== undefined) {
data.body = JSON.stringify(options);
}
return handleRequest(urlSuffix, data, errorMessage);
}
Set state
headers: {
'Content-Type': ‘application/json’,
ngapimockid: '51A82F08-CCAC-410F'
},
method: 'PUT',
body: {
identifier: 'token',
scenario: 'unauthorised'
}
Parallel execution
Not
… each scenario on each )
… all )) have the same ⚡
… all )) start with same scenario at same ⏱
… same API response on all ))
Prevent
Shortcuts
Parallel execution
Animations
Optimisation
Animations
onBoarding
Each bubble takes 500 ms to show
Min 15 bubbles => 7,5 sec
Max 25 bubbles => 12,5 sec
Bubble delay is 800 ms
Between 19 (15*800+7,5) and 32 sec (25*800+12,5) animations
What?!
Remove animations
import { AppRegistry } from 'react-native';
import App from './app/App';
import { setupAutomation } from './app/config/automation/TestProperties';
// Run the automation setup
setupAutomation();
AppRegistry.registerComponent('Tele2CustomerApp', () => App);
Remove animations
const stubs = require('stubs');
/**
* Setup the app for a specific automation build
*/
function setupAutomation() {
if (!IS_AUTOMATION_BUILD) {
return;
}
disableAnimations();
}
/**
* Disable all animations
*/
function disableAnimations() {
const AnimatedTiming = Animated.timing;
stubs(Animated, 'timing', (...props) => {
props[1].duration = 0;
props[1].delay = 0;
return AnimatedTiming(...props);
});
}
Result
Animations + real services No animation + mocking
Result
Animations + real services No animation + mocking
15 sec!40 sec!
Animations
onBoarding
Each bubble takes 500 ms to show
Min 15 bubbles => 7,5 sec
Max 25 bubbles => 12,5 sec
Bubble delay is 800 ms
Between 19 (15*800+7,5) and 32 sec (25*800+12,5) animations
What?!
Shortcuts
Parallel execution
Animations
Optimisation
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
time
per scenario
Mocking: ~4 API calls (4 x 2 sec.) ~ 8 sec.
Animations: ~ 9 sec.
Testlinkscreen: ~15 sec.
Currently 65 scenario’s
Average savings
time
per scenario
Mocking: ~4 API calls (4 x 2 sec.) ~ 8 sec.
Animations: ~ 9 sec.
Testlinkscreen: ~15 sec.
Currently 65 scenario’s
Average savings
Wow!
We just saved more than
30 min
on total execution time!
Please revert! Proceed!
time
per scenario
Mocking: ~4 API calls (4 x 2 sec.) ~ 8 sec.
Animations: ~ 9 sec.
Testlinkscreen: ~15 sec.
Currently 65 scenario’s
Average savings
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
User experience
How?
Automate comparing images
How?
Automate comparing images
Core:
• Comparison:
• ResembleJS (https://github.com/HuddleEng/Resemble.js)
How?
Automate comparing images
Core:
• Comparison:
• ResembleJS (https://github.com/HuddleEng/Resemble.js)
• Logic:
• WebdriverIO element selection
• Appium understanding (UI-hierarchy)
• Experience from the past with my protractor-image-comparison module
HOW-2-USE
// wdio.conf.js
exports.config = {
// ...
plugins: {
'wdio-native-app-compare': {
baselineFolder: '.dist/image-compare/baseline',
screenshotPath: '.dist/image-compare/screenshots',
// See Options for more options
// ..
},
},
// ...
};
HOW-2-USE
/**
* Save element
*/
// Default
device.saveElement(device.element('~your-accessibility-id'), 'name-of-your-file');
// Shorthand
device.saveElement($('~your-accessibility-id'), 'name-of-your-file');
/**
* Save screen
*/
device.saveScreen(‘name-of-your-file');
HOW-2-USE
/**
* Compare element
*/
expect(
device.compareElement(
$('~your-accessibility-id'),
'name-of-your-file',
{
// .. options here
},
).misMatchPercentage
).toEqual(0);
/**
* Compare screen
*/
expect(
device.compareScreen(
'name-of-your-file',
{
// .. options here
},
).misMatchPercentage
).toEqual(0);
React Native
0.54
React Native
0.57
, - .
React Native
0.54
React Native
0.57
, - .
, - .
Report
Report
User experience
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
Pro’s and cons
Pro’s
Increase quality
Speed up development
Test what really needs to be tested
Speed up execution time
Cons
No real services tested (automated)
App is not a production app
Developers often debug app for seeing
no animations.
(use the wrong build /)
The app
Automation setup
Happy developers
Script once
Optimisation
Time
User experience
Pro’s and cons
Menu
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
I hope we have some time left, so are there any
questions?
Can you show everybody my contact details?
I hope we have some time left, so are there any
questions?
Thank you very much!
Sure!
Contact
0: Wim Selles - Sauce Labs
1: @wswebcreation
2: wswebcreation.nl
2: gitHub.com/wswebcreation
3 Goodbye! 3

More Related Content

PDF
081107 Sammy Eclipse Summit2
mkempka
 
PPTX
React native by example by Vadim Ruban
Lohika_Odessa_TechTalks
 
PDF
Leaving Interface Builder Behind
John Wilker
 
PDF
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
PDF
Seven Versions of One Web Application
Yakov Fain
 
PPTX
Eclipse 40 and Eclipse e4
Lars Vogel
 
PDF
Angular - Improve Runtime performance 2019
Eliran Eliassy
 
PPTX
Apache Cordova In Action
Hazem Saleh
 
081107 Sammy Eclipse Summit2
mkempka
 
React native by example by Vadim Ruban
Lohika_Odessa_TechTalks
 
Leaving Interface Builder Behind
John Wilker
 
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
Seven Versions of One Web Application
Yakov Fain
 
Eclipse 40 and Eclipse e4
Lars Vogel
 
Angular - Improve Runtime performance 2019
Eliran Eliassy
 
Apache Cordova In Action
Hazem Saleh
 

What's hot (20)

PPT
Basic of Applet
suraj pandey
 
PDF
Intro to JavaScript
Yakov Fain
 
PPTX
[ApacheCon 2016] Advanced Apache Cordova
Hazem Saleh
 
PDF
ParisJS #10 : RequireJS
Julien Cabanès
 
PDF
PhoneGap: Accessing Device Capabilities
Ivano Malavolta
 
PPTX
It’s your time to ask questions
Gil Sheps
 
PDF
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Fwdays
 
PPTX
Advance JS and oop
Abuzer Firdousi
 
PDF
Lecture 22
Debasish Pratihari
 
PPTX
Eclipse e4 on Java Forum Stuttgart 2010
Lars Vogel
 
PDF
ChtiJUG - Introduction à Angular2
Demey Emmanuel
 
PDF
Introduction to Titanium and how to connect with a PHP backend
Joseluis Laso
 
PDF
Technozaure - Angular2
Demey Emmanuel
 
PDF
Arjuna - The Case of Web UI Automation with Selenium
Rahul Verma
 
PPT
Rcp by example
tsubramanian80
 
PPT
first-applet
Mohit Patodia
 
PDF
Titanium - Making the most of your single thread
Ronald Treur
 
PDF
UI Testing Best Practices - An Expected Journey
Oren Farhi
 
PDF
Best Practices in apps development with Titanium Appcelerator
Alessio Ricco
 
PPTX
[AnDevCon 2016] Mutation Testing for Android
Hazem Saleh
 
Basic of Applet
suraj pandey
 
Intro to JavaScript
Yakov Fain
 
[ApacheCon 2016] Advanced Apache Cordova
Hazem Saleh
 
ParisJS #10 : RequireJS
Julien Cabanès
 
PhoneGap: Accessing Device Capabilities
Ivano Malavolta
 
It’s your time to ask questions
Gil Sheps
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Fwdays
 
Advance JS and oop
Abuzer Firdousi
 
Lecture 22
Debasish Pratihari
 
Eclipse e4 on Java Forum Stuttgart 2010
Lars Vogel
 
ChtiJUG - Introduction à Angular2
Demey Emmanuel
 
Introduction to Titanium and how to connect with a PHP backend
Joseluis Laso
 
Technozaure - Angular2
Demey Emmanuel
 
Arjuna - The Case of Web UI Automation with Selenium
Rahul Verma
 
Rcp by example
tsubramanian80
 
first-applet
Mohit Patodia
 
Titanium - Making the most of your single thread
Ronald Treur
 
UI Testing Best Practices - An Expected Journey
Oren Farhi
 
Best Practices in apps development with Titanium Appcelerator
Alessio Ricco
 
[AnDevCon 2016] Mutation Testing for Android
Hazem Saleh
 
Ad

Similar to How React Native, Appium and me made each other shine @Frontmania 16-11-2018 (20)

PDF
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...
Wim Selles
 
PDF
How React Native Appium and me made each other shine
Wim Selles
 
PDF
ES3-2020-06 Test Driven Development (TDD)
David Rodenas
 
PDF
From 0 to 100: How we jump-started our frontend testing
Henning Muszynski
 
PPTX
The wild wild west of Selenium Capabilities
Adi Ofri
 
PDF
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
Future Processing
 
PDF
Philip Shurpik "Architecting React Native app"
Fwdays
 
PDF
Puppeteer - A web scraping & UI Testing Tool
Miki Lombardi
 
PDF
Saving Money by Optimizing Your Cloud Add-On Infrastructure
Atlassian
 
PDF
Don't let your tests slow you down
Daniel Irvine
 
PDF
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
Mek Srunyu Stittri
 
PDF
Selenium in the palm of your hand: Appium and automated mobile testing
Isaac Murchie
 
PPTX
Productive development with react js
Tim (dev-tim) Zadorozhniy
 
PPTX
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QAFest
 
PDF
SauceCon 2017: Making Your Mobile App Automatable
Sauce Labs
 
PDF
Vladyslav Romanchenko "How to keep high code quality without e2e tests"
Dakiry
 
PPTX
UI Automation Quirks
Lucas Pang
 
PDF
Mobile Development integration tests
Kenneth Poon
 
PPTX
Detox: tackling the flakiness of mobile automation
Viktorija Sujetaitė
 
PDF
React Native in Production
Seokjun Kim
 
How React Native, Appium and me made each other shine @ContinuousDeliveryAmst...
Wim Selles
 
How React Native Appium and me made each other shine
Wim Selles
 
ES3-2020-06 Test Driven Development (TDD)
David Rodenas
 
From 0 to 100: How we jump-started our frontend testing
Henning Muszynski
 
The wild wild west of Selenium Capabilities
Adi Ofri
 
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
Future Processing
 
Philip Shurpik "Architecting React Native app"
Fwdays
 
Puppeteer - A web scraping & UI Testing Tool
Miki Lombardi
 
Saving Money by Optimizing Your Cloud Add-On Infrastructure
Atlassian
 
Don't let your tests slow you down
Daniel Irvine
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
Mek Srunyu Stittri
 
Selenium in the palm of your hand: Appium and automated mobile testing
Isaac Murchie
 
Productive development with react js
Tim (dev-tim) Zadorozhniy
 
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QAFest
 
SauceCon 2017: Making Your Mobile App Automatable
Sauce Labs
 
Vladyslav Romanchenko "How to keep high code quality without e2e tests"
Dakiry
 
UI Automation Quirks
Lucas Pang
 
Mobile Development integration tests
Kenneth Poon
 
Detox: tackling the flakiness of mobile automation
Viktorija Sujetaitė
 
React Native in Production
Seokjun Kim
 
Ad

More from Wim Selles (6)

PDF
Builda responsivetypescriptwebdriverio framework
Wim Selles
 
PDF
Node.JS: Do you know the dependency of your dependencies dependency
Wim Selles
 
PDF
Building Your Own Native App Visual Testing Module with Appium
Wim Selles
 
PDF
Building Your Own Native App Visual Testing Module with Appium
Wim Selles
 
PDF
Testing beyond the default click-paths
Wim Selles
 
PDF
Why the h# should I use Appium with React Native
Wim Selles
 
Builda responsivetypescriptwebdriverio framework
Wim Selles
 
Node.JS: Do you know the dependency of your dependencies dependency
Wim Selles
 
Building Your Own Native App Visual Testing Module with Appium
Wim Selles
 
Building Your Own Native App Visual Testing Module with Appium
Wim Selles
 
Testing beyond the default click-paths
Wim Selles
 
Why the h# should I use Appium with React Native
Wim Selles
 

Recently uploaded (20)

PPTX
Mastering the DevOps Certification: CI/CD, Governance & Monitoring Made Simple
shubhamsharma994585
 
PPTX
garment-industry in bangladesh. how bangladeshi industry is doing
tanvirhossain1570
 
PDF
Thu Dinh - CIE-RESEARCH-METHODS-SLIDES-sample-extract.pptx.pdf
dinhminhthu1405
 
PPTX
Raksha Bandhan Celebrations PPT festival
sowmyabapuram
 
PDF
COSHH - Sri Ramachandar Bandi HSE in the Oil & Gas Industry (COSHH) Training ...
babufastdeals
 
PPTX
Influencing Factors of Business Environment of Vegetables Selling Business
auntorkhastagirpujan
 
PDF
SXSW Panel Picker: Placemaking: Culture is the new cost of living
GabrielCohen28
 
PDF
Chapter-52-Relationship-between-countries-at-different-levels-of-development-...
dinhminhthu1405
 
PDF
Media Training for Authors: Producing Videos & Nailing Interviews
Paula Rizzo
 
PPTX
milgram study as level psychology core study (social approach)
dinhminhthu1405
 
PPTX
Rotary_Fundraising_Overview_Updated_new video .pptx
allangraemeduncan
 
PDF
Exploring User Perspectives on Data Collection, Data Sharing Preferences, and...
Daniela Napoli
 
PDF
Helpful but Terrifying: Older Adults' Perspectives of AI in Remote Healthcare...
Daniela Napoli
 
PPTX
“Mastering Digital Professionalism: Your Online Image Matters”
ramjankhalyani
 
PDF
Green Natural Green House Presentation (2).pdf
SaeedOsman6
 
PPT
strucure of protein geomics for new .ppt
RakeshKumar508211
 
PPTX
How do Company Analysis Short Term and Long Term Investment.pptx
auntorkhastagirpujan
 
PDF
Securing Africa’s future: Technology, culture and the changing face of threat
Kayode Fayemi
 
PPTX
Public Speakingbjdsbkjfdkjdasnlkdasnlknadslnbsjknsakjscbnkjbncs.pptx
ranazunairriaz1
 
PPTX
Joy And Peace In All Circumstances.pptx
FamilyWorshipCenterD
 
Mastering the DevOps Certification: CI/CD, Governance & Monitoring Made Simple
shubhamsharma994585
 
garment-industry in bangladesh. how bangladeshi industry is doing
tanvirhossain1570
 
Thu Dinh - CIE-RESEARCH-METHODS-SLIDES-sample-extract.pptx.pdf
dinhminhthu1405
 
Raksha Bandhan Celebrations PPT festival
sowmyabapuram
 
COSHH - Sri Ramachandar Bandi HSE in the Oil & Gas Industry (COSHH) Training ...
babufastdeals
 
Influencing Factors of Business Environment of Vegetables Selling Business
auntorkhastagirpujan
 
SXSW Panel Picker: Placemaking: Culture is the new cost of living
GabrielCohen28
 
Chapter-52-Relationship-between-countries-at-different-levels-of-development-...
dinhminhthu1405
 
Media Training for Authors: Producing Videos & Nailing Interviews
Paula Rizzo
 
milgram study as level psychology core study (social approach)
dinhminhthu1405
 
Rotary_Fundraising_Overview_Updated_new video .pptx
allangraemeduncan
 
Exploring User Perspectives on Data Collection, Data Sharing Preferences, and...
Daniela Napoli
 
Helpful but Terrifying: Older Adults' Perspectives of AI in Remote Healthcare...
Daniela Napoli
 
“Mastering Digital Professionalism: Your Online Image Matters”
ramjankhalyani
 
Green Natural Green House Presentation (2).pdf
SaeedOsman6
 
strucure of protein geomics for new .ppt
RakeshKumar508211
 
How do Company Analysis Short Term and Long Term Investment.pptx
auntorkhastagirpujan
 
Securing Africa’s future: Technology, culture and the changing face of threat
Kayode Fayemi
 
Public Speakingbjdsbkjfdkjdasnlkdasnlknadslnbsjknsakjscbnkjbncs.pptx
ranazunairriaz1
 
Joy And Peace In All Circumstances.pptx
FamilyWorshipCenterD
 

How React Native, Appium and me made each other shine @Frontmania 16-11-2018