Joshua Rowe

Joshua Rowe

1573721107

Transactional Emails are Automated With Reactjs

Transactional emails are automated, realtime messages that are sent to users through email after a specific action has been performed on a website or application. These emails are often used for a wide range of alerts such as account creation, password resets, order confirmations, invoices, shipping notifications and more.

It is necessary for every business to have some sort of monitoring service for transactional emails so that you can easily detect when there’s a problem, such as when your emails keep ending up in the spam folder or when critical emails are not being delivered as expected.

In this tutorial, I’ll show you how to set up realtime monitoring of transactional emails with Pusher Channels and SendGrid. We’ll be using the scenario of a password reset email in this example, but you can easily extend it to fit other use cases.

Prerequisites

Previous experience with React and Node is required to be able to follow through with this tutorial. You also need to have Node (v8 or later) and npm installed on your computer. You can view the instructions for how to install or upgrade your Node install here.

Sign up for Channels

Before we write any code, let’s sign up for Pusher Channels and grab the necessary credentials. Once you have signed up, select Create Channels app on the sidebar to create a new app. Give your app a name and hit Create my app. Once your app is created, navigate to the API Keys tab and take note of the credentials. We’ll make use of it soon.

Sign up for SendGrid

Create a free account at Sendgrid.com. Once you’re in, select Settings > API Keys on the sidebar and then create a new API key. Give your API key a name, and select Full Access under API Key Permissions. Once your key is created, keep it in view until after we’ve added it to an .env file in the next section.

Getting started

Create a new directory for this project and cd into it. Next, run npm init -y to initialize the project with a package.json file. Following that, run the command below to install the dependencies which we’ll be needing to build the server part of the application.

    npm install express cors pusher @sendgrid/mail dotenv --save

Once the dependencies have been installed, create a new variables.env file and populate it with the following contents:

    // variables.env
    PORT=5000
    PUSHER_APP_ID=<your app id>
    PUSHER_APP_KEY=<your app key>
    PUSHER_APP_SECRET=<your app secret>
    PUSHER_APP_CLUSTER=<your app cluster>
    SENDGRID_API_KEY=<your sendgrid api key>

Next, create a new server.js file and populate it with the following contents:

    // server.js

    require('dotenv').config({ path: 'variables.env' });

    const express = require('express');
    const bodyParser = require('body-parser');
    const cors = require('cors');
    const Pusher = require('pusher');
    const sgMail = require('@sendgrid/mail')

    sgMail.setApiKey(process.env.SENDGRID_API_KEY)

    const app = express();

    app.use(cors())
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

    const pusher = new Pusher({
      appId: process.env.PUSHER_APP_ID,
      key: process.env.PUSHER_APP_KEY,
      secret: process.env.PUSHER_APP_SECRET,
      cluster: process.env.PUSHER_APP_CLUSTER,
      useTLS: true,
    });

    app.post("/reset-password", (req, res) => {
      const { email } = req.body;
      const msg = {
        to: email,
        from: 'noreply@fictionalservice.com',
        subject: 'Reset your password',
        html: `
          <p>We recently received a request to reset the password for your account.
    Simply click the button below to reset your password.</p>
          <button>Reset Password</button>
        `,
      };

      sgMail.send(msg)
        .then(() => {
          res.send("Success!");
        })
        .catch((err) => {
          console.error(err);
          res.status(500).send("An error occured");
        });
    });

    app.set('port', process.env.PORT || 5000);
    const server = app.listen(app.get('port'), () => {
      console.log(`Express running → PORT ${server.address().port}`);
    });

Our server currently has a single route which expects an email address and sends a password reset email message to it via SendGrid’s API.

You can then start the server by running node server.js in the terminal. It should become available on port 5000.

Set up the application frontend

We’ll be making use of the create-react-app tool to bootstrap our React app, so make sure you have it installed on your machine. If not, you can install it globally using npm install -g create-react-app.

By now, the create-react-app command should be available on your machine. Run the following command in the terminal to create a new React app.

    create-react-app client

As soon has the command has finished running, cd into the client directory and run the command below to install the following additional dependencies which we’ll be using to build our application frontend.

    npm install react-router-dom react-toastify axios pusher-js react-spinkit skeleton-css --save

Once all the dependencies have been installed, run npm start to start the development server. The application should be viewable at http://localhost:3000.

Create the password reset form

Open up client/src/index.js in your editor and change it to look like this:

    // client/src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { HashRouter, Route } from 'react-router-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';

    ReactDOM.render(
      <HashRouter>
        <Route exact path="/" component={App} />
      </HashRouter>
    , document.getElementById('root'));

    serviceWorker.unregister();

Next, modify the contents of client/src/App.js as follows:

    // client/src/App.js

    import React from 'react';
    import axios from 'axios';
    import logo from './logo.svg';
    import Spinner from 'react-spinkit';
    import { ToastContainer, toast } from 'react-toastify';

    import 'react-toastify/dist/ReactToastify.min.css';
    import 'skeleton-css/css/normalize.css';
    import 'skeleton-css/css/skeleton.css';
    import './App.css';

    class App extends React.Component {
      state = {
        emailAddress: '',
        loading: false,
      }

      handleChange = (event) => {
        const { value } = event.target;
        this.setState({
          emailAddress: value,
        });
      }

      handleSubmit = (event) => {
        event.preventDefault();

        const { emailAddress } = this.state;

        this.setState({
          loading: true,
        });

        axios.post("http://localhost:5000/reset-password", {
          email: emailAddress,
        }).then(() => {
          toast.success("Check your email address for the recovery link")
        })
          .catch(() => {
            toast.error("An problem occured, please try again later")
          })
          .finally(() => {
            this.setState({
              loading: false,
            })
          });
      }

      render() {
        const { emailAddress, loading } = this.state;

        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
            </header>
            <section>
              <form onSubmit={this.handleSubmit} className="password-reset" action="">
                <h5>Forgot your password? Reset it below</h5>
                <label htmlFor="email-input">Email address:</label>
                <input type="email" onChange={this.handleChange} value={emailAddress} className="email-input" placeholder="name@example.com" id="email-input" name="email" />
                <button type="submit">Email me a recovery link</button>
                { loading ? <Spinner name='line-scale-pulse-out' /> : null }
              </form>
              <ToastContainer />
            </section>
          </div>

        );
      }
    }

    export default App;

Finally, update client/src/App.css as shown below:

    // client/src/App.css

    .App {
      text-align: center;
    }

    .App-logo {
      animation: App-logo-spin infinite 20s linear;
      height: 40vmin;
      pointer-events: none;
    }

    .App-header {
      background-color: #282c34;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: calc(10px + 2vmin);
      color: white;
      margin-bottom: 20px;
    }

    .App-link {
      color: #61dafb;
    }

    @keyframes App-logo-spin {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }

    form {
      width: 100%;
      max-width: 400px;
      margin: 0 auto;
      text-align: left;
    }

    input, label {
      display: block;
      margin-bottom: 10px;
    }

    .email-input {
      margin-bottom: 20px;
    }

This part of the application is pretty simple. We have a single input where the user will enter their email address. Once the submit button is clicked, a POST request is made to the /reset-password endpoint which we set up earlier on the server.

Now, if we get a successful response (meaning an email was sent successfully), the app displays a toast notification informing the user to go check their email. Otherwise, an error message is displayed on the page.

Set up the monitoring dashboard

The next step is to set up a realtime monitoring dashboard that enables you to have a constant supervision on your transactional feeds.

Create a new Dashboard.js file in client/src and paste the following code into it:

    // client/src/Dashboard.js

    import React, { Component } from 'react';
    import Pusher from 'pusher-js';

    import './Dashboard.css';

    class Dashboard extends Component {
      state = {
        processed: 0,
        dropped: 0,
        delivered: 0,
        deferred: 0,
        bounce: 0,
      }

      componentDidMount() {
        const pusher = new Pusher('<your app key>', {
          cluster: '<your app cluster>',
          forceTLS: true
        });

        var channel = pusher.subscribe('email-events');
        channel.bind('new-event', data => {
          const { event } = data;
          this.setState(prevState => {
            return {
              [event]: prevState[event] + 1
            }
          });
        });
      }

      render() {
        const { processed, dropped, delivered, deferred, bounce } = this.state;
        return (
          <div className="Dashboard">
            <h1>Realtime Transactional Email Monitoring</h1>
            <div className="metrics">

            <div className="metric">
              <span className="metric-name">Emails Processed</span>
              <span className="metric-value">{processed}</span>
            </div>
          <div className="metric">
          <span className="metric-name">Emails Delivered</span>
          <span className="metric-value">{delivered}</span>
          </div>
          <div className="metric">
              <span className="metric-name">Emails Dropped</span>
              <span className="metric-value">{dropped}</span>
          </div>
          <div className="metric">
              <span className="metric-name">Emails Deferred</span>
              <span className="metric-value">{deferred}</span>
           </div>
          <div className="metric">
              <span className="metric-name">Bounced Emails</span>
              <span className="metric-value">{bounce}</span>
            </div>
          </div>
          </div>
        );
      }
    }

    export default Dashboard;

If you look at the componentDidMount() hook, you can see that we’re making use of the subscribe() method from Pusher to subscribe to a new channel called email-events. Finally, we’re listening for the new-event event on the email-events channel using the bind method and update the application state once we receive a new event on the channel.

Don’t forget to replace <your app id> and <your app cluster> with the appropriate values from your Channels dashboard.

Next, create the CSS file for the Dashboard component as shown below:

    // client/src/Dashboard.css

    .Dashboard {
      padding-top: 30px;
      text-align: center;
    }

    h1 {
      margin-bottom: 50px;
    }

    .metrics {
      width: 1000px;
      margin: 0 auto;
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
    }

    .metric {
      width: 130px;
      border-radius: 4px;
      border: 1px solid #ddd;
      display: flex;
      flex-direction: column;
    }

    .metric span {
      display: block;
    }

    .metric-value {
      font-size: 50px;
    }

Finally, update your client/src/index.js file as shown below:

    // client/src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { HashRouter, Route } from 'react-router-dom';
    import './index.css';
    import App from './App';
    import Dashboard from './Dashboard';
    import * as serviceWorker from './serviceWorker';

    ReactDOM.render(
      <HashRouter>
        <Route exact path="/" component={App} />
        <Route exact path="/dash" component={Dashboard} />
      </HashRouter>// If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    , document.getElementById('root'));

    serviceWorker.unregister();

Trigger updates from the server

The SendGrid Event Webhook provides realtime feedback on every email you send across nine event types. Once an email is sent, SendGrid triggers a bunch of events on a provided HTTP POST URL. We can then use the information contained in the events to update our monitoring dashboard with Channels.

First let’s set up the route on the server. Add this below the /reset-password route:

    // server.js

    app.post("/events", (req, res) => {
      const events = req.body;
      events.forEach(function (event) {
        pusher.trigger('email-events', 'new-event', {
          ...event
        });
      });
    });

Save the file and restart the server in the terminal.

Next, we need to expose our localhost server publicly using ngrok. Visit the ngrok website to find out how to set it up on your computer. Once you have it installed, start an HTTP tunnel on port 5000 by running the command below in a separate terminal window. You will be provided with a couple of URLs but you only need the last one which is HTTPS enabled.

    ./ngrok http 5000

Finally, let’s activate SendGrid’s event notification service. On the SendGrid dashboard, go to Settings > Mail Settings, and scroll to the Event Notification setting. Toggle the setting on, and click the edit link, then update the HTTP POST URL input with <your ngrok url>/events.

Following that, select the following actions: Processed, Dropped, Deferred, Delivered and Bounced, then click the blue checkmark on the right to save.

Not only will you be able to set up monitoring for your business critical emails, but you’ll be the first to know if anything goes wrong, allowing you to save time and money, and improve customer experience.

Test the application

Open the password reset form on http://localhost:3000 and the dashboard at http://localhost:3000/#/dash in a separate tab. Enter your email address and submit the form. After a short while, you should see the metrics update on the dashboard.

Wrap up

You have now learned how to create a realtime monitoring dashboard for transactional emails. It was easy wasn’t it? We covered a simple use case but you can take it further and set up monitoring for all your business’s critical emails.

Thanks for reading! Remember that you can find the source code of this app in this GitHub repository.

#reactjs #react #javascript

What is GEEK

Buddha Community

Transactional Emails are Automated  With Reactjs

Jordna Straeu

1643298528

I'm sure everyone has their own idea of what a transactional email should look like. Firstly, it can be written in different tones, for example, in a normal or professional style. But there is one thing in common for all transactional emails — they must be accurate. I know that email tracking pixel allows you to track open emails, the next steps taken by the client, and much more. It also lets you know how many times it has been opened and whether people have clicked on a specific link in an email.

Ayan Code

1656193861

Simple Login Page in HTML and CSS | Source Code

Hello guys, Today in this post we’ll learn How to Create a Simple Login Page with a fantastic design. To create it we are going to use pure CSS and HTML. Hope you enjoy this post.

A login page is one of the most important component of a website or app that allows authorized users to access an entire site or a part of a website. You would have already seen them when visiting a website. Let's head to create it.

Whether it’s a signup or login page, it should be catchy, user-friendly and easy to use. These types of Forms lead to increased sales, lead generation, and customer growth.


Demo

Click to watch demo!

Simple Login Page HTML CSS (source code)

<!DOCTYPE html>
  <html lang="en" >
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
  <link rel="stylesheet" href="styledfer.css">
  </head>

  <body>
   <div id="login-form-wrap">
    <h2>Login</h2>
    <form id="login-form">
      <p>
      <input type="email" id="email" name="email" placeholder="Email " required><i class="validation"><span></span><span></span></i>
      </p>
      <p>
      <input type="password" id="password" name="password" placeholder="Password" required><i class="validation"><span></span><span></span></i>
      </p>
      <p>
      <input type="submit" id="login" value="Login">
      </p>

      </form>
    <div id="create-account-wrap">
      <p>Don't have an accout? <a href="#">Create One</a><p>
    </div>
   </div>
    
  <script src='https://code.jquery.com/jquery-2.2.4.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.0/jquery.validate.min.js'></script>
  </body>
</html>

CSS CODE

body {
  background-color: #020202;
  font-size: 1.6rem;
  font-family: "Open Sans", sans-serif;
  color: #2b3e51;
}
h2 {
  font-weight: 300;
  text-align: center;
}
p {
  position: relative;
}
a,
a:link,
a:visited,
a:active {
  color: #ff9100;
  -webkit-transition: all 0.2s ease;
  transition: all 0.2s ease;
}
a:focus, a:hover,
a:link:focus,
a:link:hover,
a:visited:focus,
a:visited:hover,
a:active:focus,
a:active:hover {
  color: #ff9f22;
  -webkit-transition: all 0.2s ease;
  transition: all 0.2s ease;
}
#login-form-wrap {
  background-color: #fff;
  width: 16em;
  margin: 30px auto;
  text-align: center;
  padding: 20px 0 0 0;
  border-radius: 4px;
  box-shadow: 0px 30px 50px 0px rgba(0, 0, 0, 0.2);
}
#login-form {
  padding: 0 60px;
}
input {
  display: block;
  box-sizing: border-box;
  width: 100%;
  outline: none;
  height: 60px;
  line-height: 60px;
  border-radius: 4px;
}
#email,
#password {
  width: 100%;
  padding: 0 0 0 10px;
  margin: 0;
  color: #8a8b8e;
  border: 1px solid #c2c0ca;
  font-style: normal;
  font-size: 16px;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  position: relative;
  display: inline-block;
  background: none;
}
#email:focus,
#password:focus {
  border-color: #3ca9e2;
}
#email:focus:invalid,
#password:focus:invalid {
  color: #cc1e2b;
  border-color: #cc1e2b;
}
#email:valid ~ .validation,
#password:valid ~ .validation 
{
  display: block;
  border-color: #0C0;
}
#email:valid ~ .validation span,
#password:valid ~ .validation span{
  background: #0C0;
  position: absolute;
  border-radius: 6px;
}
#email:valid ~ .validation span:first-child,
#password:valid ~ .validation span:first-child{
  top: 30px;
  left: 14px;
  width: 20px;
  height: 3px;
  -webkit-transform: rotate(-45deg);
          transform: rotate(-45deg);
}
#email:valid ~ .validation span:last-child
#password:valid ~ .validation span:last-child
{
  top: 35px;
  left: 8px;
  width: 11px;
  height: 3px;
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}
.validation {
  display: none;
  position: absolute;
  content: " ";
  height: 60px;
  width: 30px;
  right: 15px;
  top: 0px;
}
input[type="submit"] {
  border: none;
  display: block;
  background-color: #ff9100;
  color: #fff;
  font-weight: bold;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-transition: all 0.2s ease;
  transition: all 0.2s ease;
  font-size: 18px;
  position: relative;
  display: inline-block;
  cursor: pointer;
  text-align: center;
}
input[type="submit"]:hover {
  background-color: #ff9b17;
  -webkit-transition: all 0.2s ease;
  transition: all 0.2s ease;
}

#create-account-wrap {
  background-color: #eeedf1;
  color: #8a8b8e;
  font-size: 14px;
  width: 100%;
  padding: 10px 0;
  border-radius: 0 0 4px 4px;
}

Congratulations! You have now successfully created our Simple Login Page in HTML and CSS.

My Website: codewithayan, see this to checkout all of my amazing Tutorials.

Origin Scale

Origin Scale

1620805745

Automation Management System

Want to try automated inventory management system for small businesses? Originscale automation software automate your data flow across orders, inventory, and purchasing. TRY FOR FREE

#automation #automation software #automated inventory management #automated inventory management system #automation management system #inventory automation

Mikel  Okuneva

Mikel Okuneva

1596848400

Automation Testing Tips

Thorough testing is crucial to the success of a software product. If your software doesn’t work properly, chances are strong that most people won’t buy or use it…at least not for long. But testing to find defects or bugs is time-consuming, expensive, often repetitive, and subject to human error. Automated testing, in which Quality Assurance teams use software tools to run detailed, repetitive, and data-intensive tests automatically, helps teams improve software quality and make the most of their always-limited testing resources.

Use these top tips to ensure that your software testing is successful and you get the maximum return on investment (ROI):

  1. Decide What Test Cases to Automate
  2. Test Early and Test Often
  3. Select the Right Automated Testing Tool
  4. Divide your Automated Testing Efforts
  5. Create Good, Quality Test Data
  6. Create Automated Tests that are Resistant to Changes in the UI

Decide What Test Cases to Automate

It is impossible to automate all testing, so it is important to determine what test cases should be automated first.

The benefit of automated testing is linked to how many times a given test can be repeated. Tests that are only performed a few times are better left for manual testing. Good test cases for automation are ones that are run frequently and require large amounts of data to perform the same action.

You can get the most benefit out of your automated testing efforts by automating:

  • Repetitive tests that run for multiple builds.
  • Tests that tend to cause human error.
  • Tests that require multiple data sets.
  • Frequently used functionality that introduces high-risk conditions.
  • Tests that are impossible to perform manually.
  • Tests that run on several different hardware or software platforms and configurations.
  • Tests that take a lot of effort and time when manual testing.

Success in test automation requires careful planning and design work. Start out by creating an automation plan. This allows you to identify the initial set of tests to automate and serve as a guide for future tests. First, you should define your goal for automated testing and determine which types of tests to automate. There are a few different types of testing, and each has its place in the testing process. For instance, unit testing is used to test a small part of the intended application. To test a certain piece of the application’s UI, you would use functional or GUI testing.

After determining your goal and which types of tests to automate, you should decide what actions your automated tests will perform. Don’t just create test steps that test various aspects of the application’s behavior at one time. Large, complex automated tests are difficult to edit and debug. It is best to divide your tests into several logical, smaller tests. It makes your test environment more coherent and manageable and allows you to share test code, test data, and processes. You will get more opportunities to update your automated tests just by adding small tests that address new functionality. Test the functionality of your application as you add it, rather than waiting until the whole feature is implemented.

When creating tests, try to keep them small and focused on one objective. For example, separate tests for read-only versus reading/write tests. This allows you to use these individual tests repeatedly without including them in every automated test.

Once you create several simple automated tests, you can group your tests into one, larger automated test. You can organize automated tests by the application’s functional area, major/minor division in the application, common functions, or a base set of test data. If an automated test refers to other tests, you may need to create a test tree, where you can run tests in a specific order.

Test Early and Test Often

To get the most out of your automated testing, testing should be started as early as possible and ran as often as needed. The earlier testers get involved in the life cycle of the project the better, and the more you test, the more bugs you find. Automated unit testing can be implemented on day one and then you can gradually build your automated test suite. Bugs detected early are a lot cheaper to fix than those discovered later in production or deployment.

With the shift left movement, developers and advanced testers are now empowered to build and run tests. Tools allow users to run functional UI tests for web and desktop applications from within their favorite IDEs. With support for Visual Studio and Java IDEs such as IntelliJ and Eclipse, developers never have to leave the comfort of their ecosystem to validate application quality meaning teams can quickly and easily shift left to deliver software faster.

Select the Right Automated Testing Tool

Selecting an automated testing tool is essential for test automation. There are a lot of automated testing tools on the market, and it is important to choose the automated testing tool that best suits your overall requirements.

Consider these key points when selecting an automated testing tool:

  • Support for your platforms and technology. Are you testing .Net, C# or WPF applications and on what operating systems? Are you going to test web applications? Do you need support for mobile application testing? Do you work with Android or iOS, or do you work with both operating systems?
  • Flexibility for testers of all skill levels. Can your QA department write automated test scripts or is there a need for keyword testing?
  • Feature-rich but also easy to create automated tests. Does the automated testing tool support record and playback test creation as well as manual creation of automated tests; does it include features for implementing checkpoints to verify values, databases, or key functionality of your application?
  • Create automated tests that are reusable, maintainable, and resistant to changes in the applications UI. Will my automated tests break if my UI changes?

For detailed information about selecting automated testing tools for automated testing, see Selecting Automated Testing Tools.

Divide Your Automated Testing Efforts

Usually, the creation of different tests is based on QA engineers’ skill levels. It is important to identify the level of experience and skills for each of your team members and divide your automated testing efforts accordingly. For instance, writing automated test scripts requires expert knowledge of scripting languages. Thus, in order to perform these tasks, you should have QA engineers that know the script language provided by the automated testing tool.

Some team members may not be versed in writing automated test scripts. These QA engineers may be better at writing test cases. It is better when an automated testing tool has a way to create automated tests that do not require an in-depth knowledge of scripting languages.

You should also collaborate on your automated testing project with other QA engineers in your department. Testing performed by a team is more effective for finding defects and the right automated testing tool allows you to share your projects with several testers.

Create Good, Quality Test Data

Good test data is extremely useful for data-driven testing. The data that should be entered into input fields during an automated test is usually stored in an external file. This data might be read from a database or any other data source like text or XML files, Excel sheets, and database tables. A good automated testing tool actually understands the contents of the data files and iterates over the contents in the automated test. Using external data makes your automated tests reusable and easier to maintain. To add different testing scenarios, the data files can be easily extended with new data without needing to edit the actual automated test.

Typically, you create test data manually and then save it to the desired data storage. However, you will find tools that provide you with the Data Generator that assists you in creating Table variables and Excel files that store test data. This approach lets you generate data of the desired type (integer numbers, strings, boolean values, and so on) and automatically save this data to the specified variable or file. Using this feature, you decrease the time spent on preparing test data for data-driven tests.

Creating test data for your automated tests is boring, but you should invest time and effort into creating data that is well structured. With good test data available, writing automated tests becomes a lot easier. The earlier you create good-quality data, the easier it is to extend existing automated tests along with the application’s development.

Create Automated Tests That Are Resistant to Changes in the UI

Automated tests created with scripts or keyword tests are dependent on the application under test. The user interface of the application may change between builds, especially in the early stages. These changes may affect the test results, or your automated tests may no longer work with future versions of the application. The problem is automated testing tools use a series of properties to identify and locate an object. Sometimes a testing tool relies on location coordinates to find the object. For instance, if the control caption or its location has changed, the automated test will no longer be able to find the object when it runs and will fail. To run the automated test successfully, you may need to replace old names with new ones in the entire project, before running the test against the new version of the application. However, if you provide unique names for your controls, it makes your automated tests resistant to these UI changes and ensures that your automated tests work without having to make changes to the text itself. This also eliminates the automated testing tool from relying on location coordinates to find the control, which is less stable and breaks easily.

#automation-testing-tool #automation-testing #automation-tips #automation-software #automation

Hollie  Ratke

Hollie Ratke

1597626000

Best Practices for Running Your Own Email Server

Plesk Premium Email, powered by Kolab lets you become your own mail service provider in a few easy steps. It’s like creating a personal Gmail service, one that you control from top to bottom. Running the mail server allows you to store your own email, access the mail server’s logs, and access the raw email files in a user’s mailbox.

However, one key concern when running your own mail server is email deliverability. Without being able to effectively reach your customer base, you cannot do business. So, how do you ensure your emails do not end up as spam?

It’s important to follow common rules and best practices when operating a mail server to guarantee your emails always reach their destination. In this quick guide, we’ll walk you through a few things to consider, to make sure that your emails always end up where you intend.

Reputation Management

Much of email delivery depends on your reputation, which is attached to your IPs and domains.

Please note that there might be different types of setups where you can either influence these things or not:

  • If you’re **running your own server **(or VPS – virtual private server) or a bunch of servers with Plesk for shared hosting with WHMCS, you have full influence and control about the following settings.
  • If you’re an **end customer or reseller **of a service provider or hoster using Plesk, unfortunately only your hosting provider can do these modifications for you. In case you want to regain control of your environments, it’s time to move your shared hosting account to your own VPS!
  • If you run Plesk on one of the hyperscale cloud providers such as DigitalOcean, Linode, AWS/Lightsail, Azure, or Google, your default email / SMTP (Port 25 or not) might be blocked on the infrastructure level. If that’s the case, you might need to contact their support to unblock it. In addition, also check that you’re receiving a reverse DNS entry for your IP that is required for operating an email server properly.

The two key-factors that we can influence are:

**1. Ensure other servers can distinguish **between genuine email coming from your server and spam coming from other servers, pretending to come from your server. If you don’t, a spammer can burn your hard-earned reputation while delivering their spam.

You can ensure this by enabling DKIM/DMARC and SPF protection in Plesk under “Server-Wide Mail Settings”.

#plesk news and announcements #email #email server #kolab #plesk email security #plesk premium email #self-hosted email #spam

First DigiAdd

1620022624

Best Email marketing strategy for Business to Reach Customer

A company can plan when to send time-based promotions or non-promotional emails using an email marketing strategy. With an email marketing strategy in place, marketers can plan out their email advertising process ahead of time.Top Email Marketing Platform

#creative email marketing services #email marketing #best email marketing services #top email marketing platform #email database & marketing services #email marketing service provider in pune