Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(load): add K6 load test workflow with example tests #1182

Merged
merged 1 commit into from Jun 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.js
Expand Up @@ -30,6 +30,9 @@ module.exports = {
'@vue-storefront/eslint-config-vue',
'@vue-storefront/eslint-config-jest',
],
globals: {
"__ENV": "readonly",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid no-undef eslint error

},
rules: {
"@typescript-eslint/no-floating-promises": "off",
"jest/expect-expect": [
Expand Down
52 changes: 52 additions & 0 deletions .github/workflows/run-k6-load-test.yml
@@ -0,0 +1,52 @@
name: Run K6 test file
on:
workflow_dispatch:
inputs:
cloud:
description: True = run in K6 cloud; False = run on the test on GitHub Actions agent
required: true
default: false
type: boolean

filename:
description: The K6 test file to run relative to repository root
required: true
default: packages/theme/tests/load/searchProduct.js
type: string

environment:
description: The full URL of the environment on which load tests will be ran
required: true
default: https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io
type: choice
options:
- https://demo-magento2-canary.europe-west1.gcp.storefrontcloud.io
- https://demo-magento2-dev.europe-west1.gcp.storefrontcloud.io
- https://demo-magento2.europe-west1.gcp.storefrontcloud.cloud
- https://demo-magento2-enterprise.europe-west1.gcp.storefrontcloud.io

flags:
description: Additional argument and flags to provide to the k6 CLI. See https://k6.io/docs/using-k6/options for details.
required: false
default: ''
type: string

jobs:
build:
name: Run k6 cloud test
runs-on: ubuntu-latest
environment: test

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Run k6 cloud test
uses: grafana/k6-action@v0.2.0
with:
cloud: ${{ inputs.cloud }}
token: ${{ secrets.K6_CLOUD_API_TOKEN }}
filename: ${{ inputs.filename }}
flags: ${{ inputs.flags }}
env:
BASE_URL: ${{ inputs.environment }}
6 changes: 3 additions & 3 deletions packages/api-client/src/api/customMutation/index.ts
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { FetchPolicy, FetchResult } from '@apollo/client/core';
import { DocumentNode } from 'graphql';
import { Context } from '../../types/context';
import getHeaders from '../getHeaders';

Expand All @@ -10,12 +10,12 @@ export default async <MUTATION = any, MUTATION_VARIABLES = any>(
mutationVariables,
fetchPolicy,
}: {
mutation: DocumentNode,
mutation: string,
mutationVariables: MUTATION_VARIABLES,
fetchPolicy?: Extract<FetchPolicy, 'network-only' | 'no-cache'>,
},
): Promise<FetchResult<MUTATION>> => context.client.mutate<MUTATION, MUTATION_VARIABLES>({
mutation,
mutation: gql`${mutation}`,
variables: { ...mutationVariables },
fetchPolicy: fetchPolicy || 'no-cache',
context: {
Expand Down
6 changes: 3 additions & 3 deletions packages/api-client/src/api/customQuery/index.ts
@@ -1,5 +1,5 @@
import gql from 'graphql-tag';
import { ApolloQueryResult, FetchPolicy } from '@apollo/client/core';
import { DocumentNode } from 'graphql';
import { Context } from '../../types/context';
import getHeaders from '../getHeaders';

Expand All @@ -10,12 +10,12 @@ export default async <QUERY = any, QUERY_VARIABLES = any>(
queryVariables,
fetchPolicy,
}: {
query: DocumentNode,
query: string,
queryVariables?: QUERY_VARIABLES,
fetchPolicy?: FetchPolicy,
},
): Promise<ApolloQueryResult<QUERY>> => context.client.query<QUERY, QUERY_VARIABLES>({
query,
query: gql`${query}`,
variables: { ...queryVariables },
fetchPolicy: fetchPolicy || 'no-cache',
context: {
Expand Down
6 changes: 3 additions & 3 deletions packages/api-client/src/types/API.ts
@@ -1,5 +1,5 @@
import { ApolloQueryResult, FetchPolicy, FetchResult } from '@apollo/client/core';
import { DocumentNode, ExecutionResult } from 'graphql';
import { ExecutionResult } from 'graphql';
import { CustomQuery } from '@vue-storefront/core';
import {
AddConfigurableProductsToCartInput,
Expand Down Expand Up @@ -278,13 +278,13 @@ export interface MagentoApiMethods {
): Promise<ApolloQueryResult<CustomerOrdersQuery>>;

customQuery<QUERY, QUERY_VARIABLES = any>(params: {
query: DocumentNode,
query: string,
queryVariables?: QUERY_VARIABLES,
fetchPolicy?: FetchPolicy,
}): Promise<ApolloQueryResult<QUERY>>;

customMutation<MUTATION, MUTATION_VARIABLES = any>(params: {
mutation: DocumentNode,
mutation: string,
mutationVariables: MUTATION_VARIABLES,
fetchPolicy?: Extract<FetchPolicy, 'network-only' | 'no-cache'>,
}): Promise<FetchResult<MUTATION>>;
Expand Down
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query getStoresAndCurrencies {
availableStores {
store_code
Expand Down
11 changes: 3 additions & 8 deletions packages/theme/composables/useApi/index.ts
@@ -1,5 +1,4 @@
import { useContext } from '@nuxtjs/composition-api';
import type { DocumentNode } from 'graphql';
import { Logger } from '~/helpers/logger';

export type FetchPolicy = 'cache-first' | 'network-only' | 'cache-only' | 'no-cache' | 'standby';
Expand All @@ -19,7 +18,7 @@ export type Error = {
};

export type Request = <DATA, VARIABLES extends Variables = Variables>(
request: DocumentNode,
request: string,
variables?: VARIABLES,
fetchPolicy?: FetchPolicy,
) => Promise<{ data: DATA, errors: Error[] }>;
Expand Down Expand Up @@ -75,10 +74,6 @@ export interface UseApiInterface {
mutate: Request;
}

function getGqlString(doc: DocumentNode) {
return doc.loc && doc.loc.source.body;
}

/**
* Allows executing arbitrary GraphQL queries and mutations.
*
Expand All @@ -93,7 +88,7 @@ export function useApi(): UseApiInterface {
variables,
) => {
const reqID = `id${Math.random().toString(16).slice(2)}`;
Logger.debug(`customQuery/request/${reqID}`, getGqlString(request));
Logger.debug(`customQuery/request/${reqID}`, request);
const { data, errors } = await context.app.$vsf.$magento.api.customQuery({ query: request, queryVariables: variables });
Logger.debug(`customQuery/result/${reqID}`, { data, errors });

Expand All @@ -106,7 +101,7 @@ export function useApi(): UseApiInterface {
variables,
) => {
const reqID = `id${Math.random().toString(16).slice(2)}`;
Logger.debug(`customQuery/request/${reqID}`, getGqlString(request));
Logger.debug(`customQuery/request/${reqID}`, request);
const { data, errors } = await context.app.$vsf.$magento.api.customMutation({ mutation: request, mutationVariables: variables });
Logger.debug(`customQuery/result/${reqID}`, { data, errors });

Expand Down
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query getCategoryContentData($filters: CategoryFilterInput) {
categoryList(filters: $filters) {
uid
Expand Down
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query getProductFiltersByCategory($categoryIdFilter: FilterEqualTypeInput!) {
products(filter: { category_uid: $categoryIdFilter }) {
aggregations {
Expand Down
@@ -1,10 +1,8 @@
import gql from 'graphql-tag';

/**
* GraphQL Query that fetches products using received search term and the params
* for filter, sort and pagination.
*/
export default gql`
export default `
query getFacetData($search: String = "", $filter: ProductAttributeFilterInput, $pageSize: Int = 10, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {
products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {
items {
Expand Down
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

const fragmentCategory = gql`
const fragmentCategory = `
fragment CategoryFields on CategoryTree {
is_anchor
name
Expand All @@ -13,7 +11,7 @@ const fragmentCategory = gql`
}
`;

export default gql`
export default `
query categoryList {
categories {
items {
Expand Down
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

export default gql`
export default `
query productsList($search: String = "", $filter: ProductAttributeFilterInput, $pageSize: Int = 20, $currentPage: Int = 1, $sort: ProductAttributeSortInput) {
products(search: $search, filter: $filter, pageSize: $pageSize, currentPage: $currentPage, sort: $sort) {
items {
Expand Down
@@ -1,6 +1,4 @@
import gql from 'graphql-tag';

const fragmentPriceRangeFields = gql`
const fragmentPriceRangeFields = `
fragment PriceRangeFields on PriceRange {
maximum_price {
final_price {
Expand All @@ -25,7 +23,7 @@ const fragmentPriceRangeFields = gql`
}
`;

export default gql`
export default `
query getProductPriceBySku($sku: String) {
products(filter: {sku: {eq: $sku}}) {
items {
Expand Down
2 changes: 1 addition & 1 deletion packages/theme/package.json
Expand Up @@ -46,7 +46,6 @@
"cookie-universal-nuxt": "^2.1.5",
"deepdash": "^5.3.9",
"express": "4.17.3",
"graphql-tag": "^2.12.6",
"is-https": "^4.0.0",
"isomorphic-dompurify": "^0.18.0",
"lodash-es": "^4.17.21",
Expand All @@ -68,6 +67,7 @@
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/user-event": "^14.2.0",
"@testing-library/vue": "^5.8.3",
"@types/k6": "^0.37.0",
"@types/lodash-es": "^4.17.6",
"@vue/test-utils": "^1.3.0",
"babel-core": "7.0.0-bridge.0",
Expand Down
4 changes: 1 addition & 3 deletions packages/theme/plugins/query/StoreConfig.gql.ts
@@ -1,7 +1,5 @@
import gql from 'graphql-tag';

/** GraphQL Query that fetches store configuration from the API */
export const StoreConfigQuery = gql`
export const StoreConfigQuery = `
query storeConfig {
storeConfig {
store_code,
Expand Down