Categories
Testing

Optimal Selector Strategies for End to End Tests

To write useful end to end tests that are stable and reliable, we have to select the correct elements all the time.

In this article, we’ll look at the optimal selector strategies to do that.

IDs

IDs are the best selectors since there’s only one of them on the page.

If it’s there, then you can select it and it’ll return the right element.

If e don’t have IDs for the element we want to select, then we should add an id attribute to the element we want to select.

We can select an ID with the # sign. For instance, we can write #foo to select an element with ID foo.

CSS and Xpath Locators

If we don’t have IDs, then we can select an element with CSS selectors.

They include classes, which is the value of the class attribute.

For instance, if we have:

<div id=”main”>
  <p>Introduction</p>
  <ul>
    <li> Item 1</li>
  </ul>
</div>

and we want to select the li element, then we have to use CSS selectors to select the element.

The easiest way to get the CSS selector is to right click on the li element.

Then click on Inspect Element in the context menu. This menu item should be available in Chromium browsers and Firefox.

This should open the developer console with the li element highlighted.

Then we right click on the element, click Copy, and click on Copy Selector. This should copy the CSS selector for the li to the clipboard.

Once we did this, we get #”main” > ul > li as the CSS, which is what we want.

Alternatively, we can use the XPath to select an element with Selenium.

It’s an expression to select nodes in HTML and XML documents.

To get the XPath, we go the developer console and right click on the element and click Copy as we did before.

Then we click Copy XPath to copy the XPath. We should get //*[@id="”main”"]/ul/li as the expression copied.

This is the relative path to the li element.

We can also click Copy Full XPath on the same menu to copy the full XPath. If we do this, we get /html/body/div/ul/li copied

Using SelectorsHub

Another way to copy an XPath is to use the SelectorsHub extension.

It’s a browser addon that’s available for Chromium browsers and Firefox.

To install the addon for Chromium browsers, we go to https://chrome.google.com/webstore/detail/selectorshub/ndgimibanhlabgdgjcpbbndiehljcpfh?hl=en

Then to use it, we right click on the element, click on SelectorsHub, then click on Copy Relative XPath.

Once we do that, we get //li[normalize-space()='Item 1']

This works if the ‘Rel XPath’ option is checked in the SelectorsHub addon and the ‘ContextMenu’ option is turned on.

We can also use it to get the CSS selector of an element.

To do this, we click on Copy Rel CSSSelector to get the CSS selector of the element in the page.

If we did that with the same example HTML above, we get div[id='”main”'] ul li.

The Copy Abs XPath option lets us copy the absolute XPath, which is the same as the full XPath in the console.

If we click that, we get /html[1]/body[1]/div[1]/ul[1]/li[1] copied to the clipboard.

Fragility

CSS Selectors and XPath are more fragile than IDs since elements may change their position in the DOM tree.

If an element changes position in the tree, then the selectors or XPath used in the current test may no longer work.

Then we have a broken test and we have to go back and fix it.

If we have to use CSS selectors and XPath, then we should make the path as short as possible to reduce complexity and the chance that the path will be outdated.

Conclusion

The best selector to use for end to end tests are always IDs.

However, if we have to use CSS selectors or XPaths, we should keep them short to improve reliability.

To get selectors for elements, we can use the browser’s development console or the SelectorHub addon.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Chips and Progress Spinners

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Truncating Text in Chips

We can truncate the text in chips by writing:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-chip
          removable
          color="primary"
          text-color="white"
          icon="cake"
          :label="label"
          :title="label"
          style="max-width: 150px;"
        >
        </q-chip>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          label: "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        }
      });
    </script>
  </body>
</html>

Circular Progress

We can add a progress spinner with Quasar.

To do this, we use the q-circular-progress component:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-circular-progress
          :value="70"
          size="50px"
          color="orange"
          class="q-ma-md"
        >
        </q-circular-progress>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

The value sets the progress value. It can be between 0 and 100.

size sets the size.

color sets the ring color.

Also, we can set the color of the center with the center-color prop:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-circular-progress
          :value="70"
          size="50px"
          color="orange"
          center-color="grey-8"
          class="q-ma-md"
        >
        </q-circular-progress>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can reverse the direction of the spinner with the reverse prop:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-circular-progress
          :value="70"
          size="50px"
          color="orange"
          center-color="grey-8"
          reverse
          class="q-ma-md"
        >
        </q-circular-progress>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can add content inside the spinner by population the default slot:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-circular-progress
          show-value
          class="text-white q-ma-md"
          :value="75"
          size="90px"
          :thickness="0.2"
          color="orange"
          center-color="grey-8"
          track-color="transparent"
        >
          <q-icon name="volume_up"></q-icon>
        </q-circular-progress>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can make the spinner spin forever with the indeterminate prop:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-circular-progress
          indeterminate
          size="50px"
          color="lime"
          class="q-ma-md"
        >
        </q-circular-progress>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Conclusion

We can add chips with long text and progress spinners into our Vue app with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Custom Chat Messages

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Chat Message with Avatars

We can add chat messages with avatars.

For instance, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We set the avatar prop to the URL of the avatar photo.

Chat Message with Time Stamp

The stamp prop lets us add a timestamp to the chat message:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
            stamp="5 minutes ago"
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
            stamp="3 minutes ago"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can add the label prop to add the label:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message label="Sunday, 20th"> </q-chat-message>
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
            stamp="5 minutes ago"
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
            stamp="3 minutes ago"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can change the background color of the chat message with the bg-color prop:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
            bg-color="amber-1"
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
            text-color="white"
            bg-color="primary"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Conclusion

We can add chat messages with various options into our Vue app with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Custom Chat Messages

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Chat Message with Avatars

We can add chat messages with avatars.

For instance, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We set the avatar prop to the URL of the avatar photo.

Chat Message with Time Stamp

The stamp prop lets us add a timestamp to the chat message:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
            stamp="5 minutes ago"
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
            stamp="3 minutes ago"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can add the label prop to add the label:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message label="Sunday, 20th"> </q-chat-message>
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
            stamp="5 minutes ago"
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
            stamp="3 minutes ago"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

We can change the background color of the chat message with the bg-color prop:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message
            name="me"
            avatar="https://cdn.quasar.dev/img/avatar1.jpg"
            :text="['hey, how are you?']"
            sent
            bg-color="amber-1"
          >
          </q-chat-message>
          <q-chat-message
            name="Mary"
            avatar="https://cdn.quasar.dev/img/avatar2.jpg"
            :text="['doing fine']"
            text-color="white"
            bg-color="primary"
          >
          </q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {}
      });
    </script>
  </body>
</html>

Conclusion

We can add chat messages with various options into our Vue app with Quasar.

Categories
Quasar

Developing Vue Apps with the Quasar Library — Carousel Controls and Chat Messages

Quasar is a popular Vue UI library for developing good looking Vue apps.

In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.

Custom Carousel Controls

We can add custom carousel controls by populating the control slot.

To do this, we write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <q-carousel
          swipeable
          animated
          v-model="slide"
          :autoplay="autoplay"
          ref="carousel"
          infinite
        >
          <q-carousel-slide
            :name="1"
            img-src="https://cdn.quasar.dev/img/mountains.jpg"
          >
          </q-carousel-slide>
          <q-carousel-slide
            :name="2"
            img-src="https://cdn.quasar.dev/img/parallax1.jpg"
          >
          </q-carousel-slide>
          <q-carousel-slide
            :name="3"
            img-src="https://cdn.quasar.dev/img/parallax2.jpg"
          >
          </q-carousel-slide>
          <template v-slot:control>
            <q-carousel-control
              position="top-right"
              :offset="[18, 18]"
              class="text-white rounded-borders"
              style="background: rgba(0, 0, 0, 0.3); padding: 4px 8px;"
            >
              <q-toggle
                dense
                dark
                color="orange"
                v-model="autoplay"
                label="Auto Play"
              >
              </q-toggle>
            </q-carousel-control>

            <q-carousel-control
              position="bottom-right"
              :offset="[18, 18]"
              class="q-gutter-xs"
            >
              <q-btn
                push
                round
                dense
                color="orange"
                text-color="black"
                icon="arrow_left"
                @click="$refs.carousel.previous()"
              >
              </q-btn>
              <q-btn
                push
                round
                dense
                color="orange"
                text-color="black"
                icon="arrow_right"
                @click="$refs.carousel.next()"
              >
              </q-btn>
            </q-carousel-control>
          </template>
        </q-carousel>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          slide: 1,
          autoplay: false
        }
      });
    </script>
  </body>
</html>

We add the position prop to position the control slot.

offset moves the slot to the left and down.

We use the class to set the colors.

We have the q-toggle component to set the autoplay reactive property to set the autoplay prop.

And we have the q-btn components to let us navigate the slides with the previous and next methods.

Chat Message

We can add the q-chat-message component to add chat message bubbles.

For instance, we can write:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message :text="['hey, how are you?']" sent></q-chat-message>
          <q-chat-message :text="['doing fine, how r you?']"></q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          slide: 1,
          autoplay: false
        }
      });
    </script>
  </body>
</html>

We set the text prop to an array of strings.

The sent prop is added to the message of the chat message of the sender.

Also, we can add the name prop to add the name of the person that sent the message:

<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
      rel="stylesheet"
      type="text/css"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
      rel="stylesheet"
      type="text/css"
    />
  </head>
  <body class="body--dark">
    <script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
    <div id="q-app">
      <q-layout
        view="lHh Lpr lFf"
        container
        style="height: 100vh;"
        class="shadow-2 rounded-borders"
      >
        <div style="width: 100%; max-width: 400px;">
          <q-chat-message
            :text="['hey, how are you?']"
            sent
            name="me"
          ></q-chat-message>
          <q-chat-message
            :text="['doing fine, how r you?']"
            name="James"
          ></q-chat-message>
        </div>
      </q-layout>
    </div>
    <script>
      new Vue({
        el: "#q-app",
        data: {
          slide: 1,
          autoplay: false
        }
      });
    </script>
  </body>
</html>

Conclusion

We can add carousels with custom controls and add chat messages into our Vue app with Quasar.