[Katalon] How to activate Katalon Studio

After the Katalon Studio has been installed by the instruction of [Katalon] How to install Katalon Studio, we have to activate Katalon Studio before using it.

The steps of activation are very simple as well as follows:
  1. Open the Katalon Studio
  2. Fill your registered Email and Password to activate Katalon Studio, then click "activate" button.


  3. Have fun with Katalon Studio

Is it easy, right? Let's do some practice for test cases in the next section.

Next: [Katalon] How to create a test case by using Record & Playback


[Katalon] How to install Katalon Studio

Note: The screenshot may differ than the actual web pages if Katalon updates their official website. (Date of the screenshot is 06/2019)

Katalon Studio is a free automation testing solution built on top of the automation frameworks Selenium, Appium with a particular IDE for API, web app and mobile app testing. By using Katalon, Git, JIRA, Slack, Jenkins, can be integrated into the automation testing flow work.

Let's learn how to install Katalon Studio in the few steps in an easy way:
      1. Go to the home page of Katalon at https://www.katalon.com/
      2. Click the "Download Now" button


      3. Create an account for activating Katalon Studio and upload the testing report to Katalon Analysis.


      4. The downloading progress of installation file according to your operating system will be started automatically. If it does not, just choose the platform from the dropdown list and click the "Download" button.


After the installation finished, we can start to "activate" Katalon Studio for further tutorials.



[GCP] How to fix "Permissions error fetching application.. " while deploying a service to an existing project

It's simple to fix this problem by the following steps:

1. use `gcloud config list` to see the setting of the current project.

2. If the `project` field is used with the project name, using "PROJECT-ID" instead by `gcloud config set project {{ PROJECT-ID }}`.

3. run `gcloud app deploy` again, this problem will be resolved.



# Reference

gcloud app deploy ERROR: Permissions error fetching application [apps/]

[Tutorial] How to use variables in Twig

The tools used in this tutorial are as following:
|Spec        | Version      |
|:------------:|--------------|
|OS          | MacOS 10.14.3|
|PHP         | >= 7.0    |
|Twig        | 2.x          |

Note. This post is written in Markdown language which has not been supported in Blogger for mobile browser yet . Please read this article by a desktop computer for a better experience.

# Introduction
Like other languages, Twig has variables and expressions for developers and designers to implement user interface template. In this section, let's see how to use variables in Twig.


# How to do
It's simple to write a variable in Twig as in PHP. 
```twig
{# if name is kitty by setting #}
  name
```


However, it will be printed as plain text in the webpage if we write a variable as above. 
```
name
```


In order to print the value of the variable, a pair of curly braces have to be used to enclose the variable.
```twig
  {# if name is kitty by setting #}
  {{ name }}
```

Then Twig template engine will print it on the webpage. ``` kitty ```
The variables are also able to be manipulated in the control structure: ```twig {% set name = 'kitty' %} {% if name is not empty %} {% set greeting = "Hello " ~ name %} {% else %} {% set greeting = "Hellow Anonymous" %} {% endif %} {{ greeting }} ```
The result is: ``` Hello kitty ```
If the variable is an object, the attributes(properties) of a variable can be accessed by a dot symbol(.). ```twig house.door ```
The attributes of a variable are also able to be accessed by "subscript" syntax. However, it doesn't work for the attributes which have special characters, such as '-', in the name. ```twig house['door'] ```
In order to let designer and developer access attributes which have special characters in the name, Twig provides `attribute()` for designer and developer to access attributes. ```twig attribute(house, 'data-door') ```
A null will be returned if a variable or attribute does not exist when the `strict_variables` option is set to false, otherwise, Twig will throw an error.
The convenient thing is multiple variables can be assigned values at the same time in one line: ```twig {% set door, room = 4, 2 %} ``` It is equivalent to: ```twig {% set door = 4 %} {% set room = 2 %} ``` # Practice Let's do some practice. The JSON object for practice is as follows: ```json { "houses":[ { "name": "1 storey house", "door": 4, "window": 4, "room": 4 }, { "name": "2 storey house", "door": 4, "window": 4, "room": 2 } ] } ```
Let's print the details of houses: ```twig {% for house in houses %} {{ house.door }} doors in {{ house.name }} {% endfor %} ```
The result will be: ``` 4 doors in 1 storey house 4 doors in 2 storey house ``` # Setting Variables The variables can be set a value, such as string, integer, floating number, array, and key-value pairs, by Control Structure in a variant way. ## Set a string to a variable ```twig {% set var = 'this is a string' %} {# Tests the result #} {{ var }} ``` The result will be ``` this is a string ```
## Set an integer to a variable ```twig {% set var = 15 %} {# Tests the result #} {{ var }} ```
The result will be ``` 15 ```
## Set a floating number to a variable ```twig {% set var = 12.33456 %} {# Tests the result #} {{ var }} ```
The result will be ``` 12.33456 ```
## Set a string array to a variable ```twig {% set string_array = ['one', 'two', 'three', 'four'] %}
{# Tests the result #} {% for str in string_array %} {{ str }} {% endfor %} ```
The result will be ``` one two three four ```
## Set an integer array to a variable ```twig {% set integer_array = [1, 2, 3, 4] %} {# Tests the result #} {% for int in integer_array %} {{ int }} {% endfor %} ```
The result will be ``` 1 2 3 4 ```
## Set a floating number array to a variable ```twig {% set float_array = [1.1, 2.2, 3.3, 4.4] %}
{# Tests the result #} {% for float in float_array %} {{ float }} {% endfor %} ```
The result will be ``` 1.1 2.2 3.3 4.4 ```
## Set key-value pairs to a variable, and the key is string ```twig {% set map_str_key = {'one': 'first', 'two': 'second', 'three': 'third'} %} {# Tests the result #} {% for key, value in map_str_key %} [{{ key }}] = {{ value }} {% endfor %} ```
The result will be ``` [one] = first [two] = second [three] = third ```
## Set key-value pairs to a variable, and the key is integer ```twig {% set map_int_key = {1: 'first', 2: 'second', 3: 'third'} %} {# Tests the result #} {% for key, value in map_int_key %} [{{ key }}] = {{ value }} {% endfor %} ```
The result will be ``` [1] = first [2] = second [3] = third ```
If we store key as an integer, we can use square brackets(`[]`) to manipulate this variable: ```twig {# this will throw an error [0] = {{ map_int_key[0] }} #}
[1] = {{ map_int_key[1] }} [2] = {{ map_int_key[2] }} [3] = {{ map_int_key[3] }} ```
The result is: ``` [1] = first [2] = second [3] = third ```
When we use this approach to manipulate the variable, we must be careful that does not access the key which doesn't exist. Otherwise, an error will be thrown.
## Set a block of value to the variable The `set tag` not only accepts a line of value but also accepts a multiple lines value. Let's see how to implement it. If we want to use a set block to set value, the value should be enclosed by `{%set ... %}` and `{% endset %}`. ```twig {% set integer_array = [1,2,3,4] %} {% set ints %} <ol> {% for int in integer_array %} <il>{{ int }}</il> {% endfor %} </ol> {% endset %} {# Shows the result #} {{ ints }} ```
The result is ```html <ol> <il>1</il> <il>2</il> <il>3</il> <il>4</il> </ol> ```
However, the `{% set ... %} ... {% endset %}` code block doesn't convert JSON string into an object and it cannot be used to assign key-value pairs: ```twig {% set home %} { 'door': 4, 'room': 2, 'toilet': 1 } {% endset %} {# Shows the result #} {{ home }} {# this doesn't show anything #} {% for item in home %} {{ item }} {% endfor %} {# this will throw error #} {{ home['door'] }} ```
The result is: ``` { 'door': 4, 'room': 2, 'toilet': 1 } ```
As a result, the `{% set ... %} ... {% endset %}` code block only treats the value as text as the demonstration in the [official document](https://twig.symfony.com/doc/2.x/tags/set.html). If we use HTML tags assigned to the variables in this sort of code block and automatic output escaping is enabled, the HTML tags will be encoded to make sure the content is safe. ```twig {% set trh = '<tr>' %} {% set tre = '</tr>' %} {% set tdh = '<td>' %} {% set tde = '</td>' %} {% set table %} <table> {{ trh }} {{ tdh }} cell 1 {{ tde }} {{ tdh }} cell 2 {{ tde }} {{ tdh }} cell 3 {{ tde }} {{ trh }} {{ trh }} {{ tdh }} cell 4 {{ tde }} {{ tdh }} cell 5 {{ tde }} {{ tdh }} cell 6 {{ tde }} {{ trh }} </table> {% endset %} {# shows the result #} {{ table }} ```
The result will be: ```html <table> &lt;tr&gt; &lt;td&gt; cell 1 &lt;/tr&gt; &lt;td&gamp;t; cell 2 &lt;/tr&gt; &lt;td&gt; cell 3 &lt;/tr&gt; &lt;tr&gt; &lt;tr&gt; &lt;td&gt; cell 4 &lt;/tr&gt; &lt;td&gt; cell 5 &lt;/tr&gt; &lt;td&gt; cell 6 &lt;/tr&gt; &lt;tr&gt; <table> ``` ## Variable Scope If a variable has been declared inside a `for` loop, it cannot be accessed outside of the loop. ```twig {% set list=[1,2,3,4,5] %} {% for i in list %} {% set result = i %} {% endfor %} {# An error will be thrown #} {{ result }} ```
But it can be accessed if it has been declared outside the loop: ```twig {% set list=[1,2,3,4,5] %} {% set result = 0 %} {% for i in list %} {% set result = i %} {% endfor %} {# The result is 5 #} {{ result }} ```
# Filter A filter can be applied to the variables to trim space, lowercase all of the characters, merge an array and so on. ```twig {% set name = ' Kitty' %} {# this will print 'Kitty' instead of ' Kitty' #} {{ name }} ```
This will be introduced in the next tutorial.
# Reference [Twig Variables](https://twig.symfony.com/doc/2.x/templates.html#variables) [set Tag](https://twig.symfony.com/doc/2.x/tags/set.html) ## Relevant Readings [How to setup development environment for Twig on MacOS](https://totsi04.blogspot.com/2019/02/tutorial-how-to-setup-development.html)

Find Window's Handle through PID

```cpp
typedef _ProcessHwnd

{

  DWORD ProcessID;
  HWND hwndProcess;

} PROCESSHWND, * PPROCESSHWND;


DWORD GetHWNDForProcess(DWORD ProcessID, PHWND ProcessHWND);
BOOL CALLBACK FindProcessHWNDThruEnum(HWND hwnd, LPARAM lParam);

// example function
// returns 0 if success, results of GetLast Error if not
// ProcessID is the process you are interested in
// ProcessHWND will have the process' associated window handle.
// Or NULL, if the process doesn't have a window
//
// Usage: GetHWNDForProcess(ProcId, &ProcHWND);
//

DWORD GetHWNDForProcess(DWORD ProcessID, PHWND ProcessHWND)
{
  DWORD ErrValue = 0;
  BOOL fEnumWindows = FALSE;
  PROCESSHWND prochwndFind;

// Initialize the structure
  memset(&prochwndFind, 0, sizeof(prochwndFind));
  prochwndFind.ProcessID = ProcessID;
  fEnumWindows = EnumWindows(FindProcessHWNDThruEnum, (LPARAM) &prochwndFind);

// Make sure EnumWindows succeeded
  if(fEnumWindows){
    *ProcessHWND = prochwndFind.hwndProcess;
  }else{
   ErrValue = GetLastError();
  }
  return ErrValue;
}

// The EnumWindowsProc callback
BOOL CALLBACK FindProcessHWNDThruEnum(HWND hwnd, LPARAM lParam)
{
  PPROCESSHWND prochwndFind;
  DWORD ThisProcessID = 0;
  DWORD ThisThreadID = 0; // For completeness, not needed

  prochwndFind = (PPROCESSHWND) lParam;
  ThisThreadID = GetWindowThreadProcessId(hwnd, &ThisProcessID);

  if(ThisProcessID == prochwndFind.ProcessID)
  {
    prochwndFind.hwndProcess = hwnd);
    return FALSE;
  }else{
    return TRUE;
  }
}
```

[Tutorial] How to setup development environment for Twig on MacOS

The tools used in this tutorial are as following:
OS                 : MacOS 10.14.3
PHP version : >= 7.0
Twig version : 2.x

Introduction
Twig is a template engine for the web developers and designers to implement user interface template in PHP by built-in tags, filters, and functions. The benefit of using Twig to implement user interface template is enhancing the readability of code, reducing the complexity of code, and making it be extendable because the templates can be inherited and included in other templates in Twig. It sounds great, right? So, let's have a try with Twig right now.


IDE
According to the document from Twig, it shows that there are plenty of editors which are able to be used to implement Twig template. In this case, I chose Visual Studio Code as my IDE due to that I can have lots of extensions which helps me backup settings, highlight syntax and provide auto-completion for Twig template. The best thing is it's fast than Netbeans and Eclipse I used to implement projects in PHP and Java. Also, TwigFiddle is a very good online Twig template editor which provides varieties of Twig in different version and the template can be saved online. Furthermore, the testing data can be filled to test the Twig template in real-time. Or you can find other IDE and extensions by click here.

To install Twig Packs for VSC, please refer to the following photo:

Installation
In order to run a Twig template on the local machine, the Twig template engine has to be installed via Composer. The command for Twig template engine installation is as follows:

```sh
composer require "twig/twig:^2.0"
```

That's it. It's simple, right?

Trouble Shooting
Q: Where I can find my default PHP?
A: Execute  which php  

Q: What can I do if 'php -version' still shows php v5.x?
A:
Normally, the default PHP is allocated at `/usr/bin` on macOS. So, just edit your `~/.bash_profile` and insert `export PATH=/usr/bin:$PATH` in this file. After that, just execute `. ~/.bash_profile` to update settings.

Q: What can I do if I got Permission Denied when using composer to install Twig? A: By default, composer is installed in /vendor. So, just run the command as follows:
 sudo chown -R $USER /vendor  

Reference
Twig Install Twig by composer

Composer: file_put_contents(./composer.json): failed to open stream: Permission denied

How to avoid shopping on a fraud website

As for the post about the frauds ads on Facebook, I would like to share some basic tricks to let you get rid of the fraud website.

1. Domain name is always as same as the brand name.
 The fraud website cannot use the official domain registered by the brand already. If the website represents the official website, check the domain name first. But read the domain name carefully, some fraud side will use a similar name to cheat you, such as www.leg0.com or www.Iego.com. The best way is to google the name of the shop and sees if Google can find it. Also, check the details what Google shows to you.


2. The layout(details) of the website

If the layout of the website is awful or everything mixed together, you should be careful that it must be a fraud website. For instance, this website screenshot the rating, but not to implement it. If you can not see any review on the website, it must be a fraud.


3. Do not pay by Credit Card or Bank Transfer 
 The scammers will reuse your card details to make more requests. Pay by PayPal or other organisations which can suspend/hold the payment when you make a dispute is the best choice.


4. Do more research before you place an order
 Use the keyword on the website on Google to see how many people visit this site and interacted with it. Just be careful the fraud review because the scammers are not along.


If you still cannot make sure that website is a fraud or not, just leave it alone and ignore the popup ads from the social media because it is not worth to pay the money you got by your hard working.


May the force be with you.

Useful Links: (Before clicking the link below, it's a good practice to google the title of links for avoiding phishing)

Beware of the fraud ads on Facebook timeline

It's not about the coding but this can save your pocket. My wife tried to buy a Christmas gift for me from an online shop which pretends as an official Lego website and advertises on Facebook. The website looks like the official one on the mobile, however, it doesn't do it well for the desktop version.

The photo of products looks like the official one. If I don't open it on my laptop, I won't find the awful design of this website. So, please check the details, such as the rating, of the product before place an order. The rating on this page is photocopied so that we cannot see the actual review or rating. This shop tries to create more new Facebook accounts and advertise on it, even someone report the fraud ads to Facebook.



I'm so so sorry for that it makes my wife lose $100. As a result, Do not buy anything from the ads on Facebook to prevent fraud ads. Just Google the name of the shop which you already knew and someone has bought something from it. Or chose the shop which accepts PayPal, then you may have a chance to get your money back if it's a fraud shop, but you still have to take a risk. In my opinion, the best way is that only buy the stuff from wherever you trust.

By the way, don't click the ads underneath this post which provided by Google if you don't know that shop. I trust Google but people make mistake as same as me. Good luck, guys.

Build docker image from multiple build contexts

Build docker image from multiple build contexts ...