Cypress ReactJs tests Fail to find elements on Gitlab CI - reactjs

I am testing some Reactjs UI with Cypress. When I run the tests locally using localhost:3000, the tests pass but when I push to Gitlab CI, the tests fail and the error is as shown below.
CypressError: Timed out retrying: Expected to find element: '.css-iyxtew', but never found it.
This is not due to server delay, I have tried adding wait time in vain. My guess is that the localhost server on Gitlab is not okay. Please help me with any solutions.
beforeEach(() => {
cy.visit('localhost:3000')
eslint-disable-next-line no-return-assign
cy.window().then(win => win.onbeforeunload = undefined)
})
it('Does not do much!', () => {
expect(true).to.equal(true)
})
it('.should() - make an assertion about the current page', () => {
cy.get('[data-cy=loader]').find('h6').should('be.visible')
cy.get('body').should('be.visible')
cy.get('.css-iyxtew').should('be.visible')
cy.get('[data-cy=index-page]').find('[data-cy=heading]').should('be.visible')
cy.get('.css-iyxtew').find('li').should('have.length', 2)
.find('.login').find('.css-17nm302-Button')
.should('have.css', 'background-color', 'rgba(0, 0, 0, 0)')
cy.get('.main-section').should('exist').find('.left-nav ').should('exist')
.find('.left-margin-pane').should('exist')
cy.get('.heading').find('.sub-heading')
.contains('Choose a phase below to browse our growing collection of adaptive implementation resources')
})

The solution I found out after some time is that I needed to add env variables to the CI environment too for the server to run.
this is gitlab-ci.yml
variables:
GET_PHASE_KITS: $GET_PHASE_KITS
GET_KIT: $GET_KIT
GET_PHASE_ASSETS: $GET_PHASE_ASSETS
GET_USER: $GET_USER
CREATE_USER: $CREATE_USER
ADD_USER_KIT: $ADD_USER_KIT
GET_USER_BY_ID: $GET_USER_BY_ID
GET_PHASES: $GET_PHASES
ADD_USER_ASSET: $ADD_USER_ASSET
GET_ASSET: $GET_ASSET
GET_PHASE: $GET_PHASE
EDIT_USER: $EDIT_USER

Related

Nextjs 12 Error When Running on Cloud Run But Works Well on Localhost

I'm trying to upgrade from nextjs v10 to v12. It successfully worked at localhost, but when deployed on cloud run and running on the active domain, it shows 500 Internal Server Error. Previously it worked well on cloud run with nextjs v10.
I create a test page to check what makes it error and after testing, it may seems the 'getServerSideProps' is the problem.
Here is my code, /pages/test2.js
import Layout from 'components/layout'
export async function getServerSideProps({ req, res }) {
return {
props: {
data: { title: 'test' },
},
}
}
export default function Test({ data }) {
console.log('testtt', data)
return (
<Layout activeId="home">
<div>ABC TEsT</div>
</Layout>
)
}
If I remove 'getServerSideProps' function then deploy to cloud run, then the page is working well.
Here is the error found on cloud run server log
SyntaxError : Unexpected token '.'
Link to error image
The weird thing is, there is no error on localhost.
Is there any problem with getServerSideProps on nextjs v12 or I am missing configuration?
I have no custom webpack and babel config.
Thank you

Unit Tests Failing After Updating React Scripts from v.3.4.4 to v.4.0.3

I'm working on a new project for a client and have been asked to update create-react-app (react-scripts) from v.2.0.5 to v.4.0.3. I did that, and a bunch of unit tests failed. I went back through the project and isolated the breaking change to be the update from react-scripts 3.4.4 to 4.0.0.
Basically, the main error I'm seeing seems to apply to any tests running against async/await methods. Jest reports that the test times out but these tests are only timing out because they are failing. They all pass without issue on an earlier version of react-scripts (and by extension an earlier version of Jest I'd guess).
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
The timeout seems to be relating to an issue with promises as it's preceeded by this error:
TypeError: Cannot read property 'then' of undefined
Along with a fairly indecipherable stack trace that lists a load of node modules.
Here's an example of the test that's failing:
test('dispatching fetchPublishedArticlesAuthors action causes an API GET and updates the store', async (done) => {
const options = { page: 0, size: 20, sort: 'createdBy.firstName,asc' };
store.dispatch(fetchPublishedArticlesAuthors(options));
const state = await stateChange(store);
expect(fetch).toHaveBeenCalledWith(
`https://content.onehub.test/articles/authors?page=0&size=20&sort=createdBy.firstName%2Casc`,
expect.objectContaining({ method: 'GET' }),
);
expect(getPublishedArticlesAuthors(state)).toMatchSnapshot();
done();
});
The await stateChange(store) references this method:
export function stateChange(store) {
return new Promise((resolve) => {
let currentState = store.getState();
store.subscribe(() => {
const newState = store.getState();
if (newState !== currentState) {
resolve(newState);
}
currentState = newState;
});
});
}
This method works without issue on another project running react-scripts 4.0.3 so I don't think that it's the issue per se but it is failing to return anything if I'm not mistaken.
Store is mocked as follows:
beforeEach(() => {
store = mockStore({ initialState, reducers, rootSaga: sagas });
fetch.mockClear();
});
Any tips on where to start? Confused as to why it fails on a more recent version but passes on an earlier one.
The solution was to set resetMocks to false. I tried doing this in Jest config but couldn't get it working so just added it directly to package.json:
"jest": {
"resetMocks": false
}
It wasn't obvious from the failing tests but having read the release notes you can see that the version of Jest used by Create React App changed from v24 to v26. In the process, resetMocks is set to true which was breaking the implementation in the test above, causing them all to time out.

Webview context doesn't show up anymore when testing using Appium

I am creating an automation test using Appium and webdriverio:
const wdio = require("webdriverio");
const opts = {
path: "/wd/hub",
port: 4723,
capabilities: {
platformName: "Android",
platformVersion: "11",
deviceName: "Android Emulator",
app: "/path/to/myapk.apk",
automationName: "UiAutomator2",
autoGrantPermissions: true
}
};
async function main() {
const driver = await wdio.remote(opts);
const contexts = await driver.getContexts();
console.log("Contexts:", contexts);
await driver.deleteSession();
}
main();
The problem
When running tests I could see that I used to have two contexts:
NATIVE_APP
WEBVIEW_chrome (or similar, I do not remember exactly the value here)
I then made a change which switched contexts to the webview, there I got an error about the chrome driver not being found. That is when I installed it: npm install "appium-chromedriver".
I do not know if this is what made everything go babanas, but since then, everytime I test, I can only see the native context, no more webview context :(
More info
It is important to point out that I have modified my Android app to include this:
#Override
public void onCreate() {
super.onCreate();
WebView.setWebContentsDebuggingEnabled(true);
}
I can also start chrome://inspect and see the webview is there and even inspect it. But when running tests, the driver cannot see the webview context.
Why? How to fix this?
Turns out that I need to wait for a webview to show up in the app, so this works:
async function main() {
const driver = await wdio.remote(opts);
// Wait a few seconds so the webview properly loads
await new Promise(resolve => setTimeout(resolve, 5000));
const contexts = await driver.getContexts();
console.log("Contexts:", contexts);
await driver.deleteSession();
}

How to use react-native-i18n in detox[react-native]

I want to test the alert message in detox,and the message use i18n.
const i18n = require("react-native-i18n");
describe("Example", () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it("should show hello screen after tap", async () => {
await element(by.id("btnLogin")).tap();
I18n.t(LocaleKeys.errorMsg_invalidUsername);
await expect(element(by.text(I18n.t(LocaleKeys.errorMsg_invalidUsername)))).toBeVisible();
// await expect(element(by.text("Please input the email and password."))).toBeVisible();
});
});
Run test and get the following error.
Test suite failed to run
/Users/leogeng/Desktop/studentREP/student-app/node_modules/react-native-i18n/index.js:14
export const getLanguages = () => RNI18n.getLanguages();
^^^^^^
SyntaxError: Unexpected token export
at ScriptTransformer._transformAndBuildScript (../node_modules/jest-runtime/build/script_transformer.js:305:17)
at Object.<anonymous> (firstTest.spec.js:1:114)
at Generator.next (<anonymous>)
Then I add the following code for jest:
{
"preset": "react-native",
"transformIgnorePatterns": [
"/node_modules/(?!(react-native(.*)?/|native-base(.*)?/|react-navigation/))"
]
}
and get error again:
Validation Error:
Module <rootDir>/node_modules/react-native/jest/setup.js in the setupFiles option was not found.
Actually i confirm 'setup,js' exist in node_modules/react-native/jest.
I do not know why the error happens, anybody can help me?
Thanks
Most likely it's because you're using an old version of node, try to update and see if it solves the issue. Also, it's completely unrelated to Jest and you should probably revert your attempts to modify Jest settings if you don't have any issues with Jest unit tests; in anyway, it will not fix the detox issues.
In case you have some requirement or reason which forces you to keep node at a specific old version, you can bypass it by performing the test differently: have a demo screen only for the e2e tests (or even create a whole demo project just for e2e), in the demo screen you can have a button which performs what you need with i18n (changing locale or whatever), and in the detox test you tap this "demo" button before testing what you actually want.
I've had the same problem. I resolve it by importing i18n-js instead of react-native-i18n.
Because react-native-i18n is not a plain javascript framework, Detox can't import it.
But react-native-i18n is using i18n-js, so you can access your translations without any problem
const I18n = require('i18n-js')
// and then you can use it for your tests
...
await element(by.text( I18n.t('hello') )).tap()

importScripts in Web Workers is undefined inside a React/Webpack environment

I am working on a React app created with create-react-app. I was having trouble creating a web worker in it so I posted a question here on SO: Creating a web worker inside React
I've found a solution, as written in the post above, to load a worker without ejecting the app and messing with the Webpack config. This is the code, from the post above:
// worker.js
const workercode = () => {
self.onmessage = function(e) {
console.log('Message received from main script');
const workerResult = 'Received from main: ' + (e.data);
console.log('Posting message back to main script');
self.postMessage(workerResult);
}
};
let code = workercode.toString();
code = code.substring(code.indexOf("{")+1, code.lastIndexOf("}"));
const blob = new Blob([code], {type: "application/javascript"});
const worker_script = URL.createObjectURL(blob);
module.exports = worker_script;
and in the file that uses the worker:
import worker_script from './worker';
const myWorker = new Worker(worker_script);
myWorker.onmessage = (m) => {
console.log("msg from worker: ", m.data);
};
myWorker.postMessage('im from main');
It works, however, I cannot seem to get importScripts to work. Even if I do this (outside onmessage or inside onmessage):
if (typeof importScripts === 'function') {
importScripts('myscript.js');
}
In that case, the if statement turns out to be true, but then fails on the actual import with the same error message 'importScripts' is not defined as if the if statement is a false positive, which doesn't sound right. I'd say this is a context issue and that the worker probably isn't loading properly (although it seems to work), but it's just a guess.
Any ideas what's happening here?
importScripts in a worker created from Blob works fine, at least in 2021 (react 17.0.2, react-scripts 4.0.3, Chrome 92). The imported script URL must be absolute because worker was created from Blob.
The original issue might have been a bug in webpack or the transpilation might have changed the code in a weird way.
const workercode = () => {
importScripts("https://example.com/extra.js");
console.log(self.extraValue); // 10
self.onmessage = function(e) {
console.log('Message received from main script');
...
}
};
 
// extra.js
self.extraValue = 10;
Looks like this is still broken in 2022 - Seems there is a regression coming down the dev pipeline (at least in Android WebView and possibly some dev/canary chrome verions.)
https://bugs.chromium.org/p/chromium/issues/detail?id=1078821

Resources