diff --git a/superset-frontend/spec/javascripts/components/Menu_spec.jsx b/superset-frontend/spec/javascripts/components/Menu_spec.jsx
deleted file mode 100644
index 3b28388d11090..0000000000000
--- a/superset-frontend/spec/javascripts/components/Menu_spec.jsx
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import React from 'react';
-import { styledMount as mount } from 'spec/helpers/theming';
-import { shallow } from 'enzyme';
-import { Nav } from 'react-bootstrap';
-import { Menu as DropdownMenu } from 'src/common/components';
-import NavDropdown from 'src/components/NavDropdown';
-import { Link } from 'react-router-dom';
-
-import { Menu } from 'src/components/Menu/Menu';
-import MenuObject from 'src/components/Menu/MenuObject';
-
-const defaultProps = {
- data: {
- menu: [
- {
- name: 'Home',
- icon: '',
- label: 'Home',
- url: '/superset/welcome',
- },
- {
- name: 'Sources',
- icon: 'fa-table',
- label: 'Sources',
- childs: [
- {
- name: 'Datasets',
- icon: 'fa-table',
- label: 'Datasets',
- url: '/tablemodelview/list/',
- },
- '-',
- {
- name: 'Databases',
- icon: 'fa-database',
- label: 'Databases',
- url: '/databaseview/list/',
- },
- ],
- },
- {
- name: 'Charts',
- icon: 'fa-bar-chart',
- label: 'Charts',
- url: '/chart/list/',
- },
- {
- name: 'Dashboards',
- icon: 'fa-dashboard',
- label: 'Dashboards',
- url: '/dashboard/list/',
- },
- ],
- brand: {
- path: '/superset/profile/admin/',
- icon: '/static/assets/images/superset-logo-horiz.png',
- alt: 'Superset',
- width: '126',
- },
- navbar_right: {
- bug_report_url: null,
- documentation_url: null,
- languages: {
- en: {
- flag: 'us',
- name: 'English',
- url: '/lang/en',
- },
- it: {
- flag: 'it',
- name: 'Italian',
- url: '/lang/it',
- },
- },
- show_language_picker: true,
- user_is_anonymous: false,
- user_info_url: '/users/userinfo/',
- user_logout_url: '/logout/',
- user_login_url: '/login/',
- locale: 'en',
- },
- settings: [
- {
- name: 'Security',
- icon: 'fa-cogs',
- label: 'Security',
- childs: [
- {
- name: 'List Users',
- icon: 'fa-user',
- label: 'List Users',
- url: '/users/list/',
- },
- ],
- },
- ],
- },
-};
-
-describe('Menu', () => {
- let wrapper;
-
- const getWrapper = (overrideProps = {}) => {
- const props = {
- ...defaultProps,
- ...overrideProps,
- };
- return shallow(
);
- };
-
- beforeEach(() => {
- wrapper = getWrapper();
- });
-
- it('renders the brand', () => {
- expect(wrapper.find('.navbar-brand')).toExist();
- });
-
- it('renders 2 navs', () => {
- expect(wrapper.find(Nav)).toHaveLength(2);
- });
-
- it('renders 4 elements in main Menu Nav for every user', () => {
- expect(wrapper.find(MenuObject)).toHaveLength(4);
- });
-
- it('renders a logged out view', () => {
- const loggedOutWrapper = getWrapper({
- data: {
- ...defaultProps.data,
- navbar_right: {
- ...defaultProps.data.navbar_right,
- user_is_anonymous: true,
- },
- },
- });
- expect(loggedOutWrapper.find('i.fa-sign-in')).toHaveLength(1);
- expect(loggedOutWrapper.find('i.fa-user')).toHaveLength(0);
- });
-
- it('renders version number and SHA', () => {
- const overrideProps = {
- data: {
- ...defaultProps.data,
- navbar_right: {
- ...defaultProps.data.navbar_right,
- version_string: 'A1',
- version_sha: 'X',
- },
- },
- };
-
- const props = {
- ...defaultProps,
- ...overrideProps,
- };
-
- const versionedWrapper = mount();
-
- expect(versionedWrapper.find('.version-info span')).toHaveLength(2);
- });
-
- it('renders a NavDropdown (settings)', () => {
- expect(wrapper.find(NavDropdown)).toHaveLength(1);
- });
-
- it('renders MenuItems in NavDropdown (settings)', () => {
- expect(wrapper.find(NavDropdown).find(DropdownMenu.Item)).toHaveLength(3);
- });
-
- it('renders a react-router Link if isFrontendRoute', () => {
- const props = {
- ...defaultProps,
- isFrontendRoute: jest.fn(() => true),
- };
-
- const wrapper2 = mount();
-
- expect(props.isFrontendRoute).toHaveBeenCalled();
- expect(wrapper2.find(Link)).toExist();
- });
-
- it('does not render a react-router Link if not isFrontendRoute', () => {
- const props = {
- ...defaultProps,
- isFrontendRoute: jest.fn(() => false),
- };
-
- const wrapper2 = mount();
-
- expect(props.isFrontendRoute).toHaveBeenCalled();
- expect(wrapper2.find(Link).exists()).toBe(false);
- });
-});
diff --git a/superset-frontend/spec/javascripts/components/SubMenu_spec.jsx b/superset-frontend/spec/javascripts/components/SubMenu_spec.jsx
deleted file mode 100644
index 46259328f8401..0000000000000
--- a/superset-frontend/spec/javascripts/components/SubMenu_spec.jsx
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import React from 'react';
-import { Link } from 'react-router-dom';
-import { shallow } from 'enzyme';
-import { Navbar } from 'react-bootstrap';
-import SubMenu from 'src/components/Menu/SubMenu';
-
-const defaultProps = {
- name: 'Title',
- tabs: [
- {
- name: 'Page1',
- label: 'Page1',
- url: '/page1',
- usesRouter: true,
- },
- {
- name: 'Page2',
- label: 'Page2',
- url: '/page2',
- usesRouter: true,
- },
- {
- name: 'Page3',
- label: 'Page3',
- url: '/page3',
- usesRouter: false,
- },
- ],
-};
-
-describe('SubMenu', () => {
- let wrapper;
-
- const getWrapper = (overrideProps = {}) => {
- const props = {
- ...defaultProps,
- ...overrideProps,
- };
- return shallow();
- };
-
- beforeEach(() => {
- wrapper = getWrapper();
- });
-
- it('renders a Navbar', () => {
- expect(wrapper.find(Navbar)).toExist();
- });
-
- it('renders 3 MenuItems (when usesRouter === false)', () => {
- expect(wrapper.find('li')).toHaveLength(3);
- });
-
- it('renders the menu title', () => {
- expect(wrapper.find(Navbar.Brand)).toExist();
- expect(wrapper.find(Navbar.Brand).children().text()).toEqual('Title');
- });
-
- it('renders Link components when usesRouter === true', () => {
- const overrideProps = {
- usesRouter: true,
- };
-
- const routerWrapper = getWrapper(overrideProps);
-
- expect(routerWrapper.find(Link)).toExist();
- expect(routerWrapper.find(Link)).toHaveLength(2);
- expect(routerWrapper.find('li.no-router')).toHaveLength(1);
- });
-
- it('renders buttons in the right nav of the submenu', () => {
- const mockFunc = jest.fn();
- const buttons = [
- {
- name: 'test_button',
- onClick: mockFunc,
- buttonStyle: 'primary',
- },
- {
- name: 'danger_button',
- buttonStyle: 'danger',
- },
- ];
- const overrideProps = { buttons };
- const newWrapper = getWrapper(overrideProps);
- expect(newWrapper.find('.navbar-right').children()).toHaveLength(2);
- newWrapper.find('[buttonStyle="primary"]').simulate('click');
- expect(mockFunc).toHaveBeenCalled();
- });
-});
diff --git a/superset-frontend/src/components/Menu/LanguagePicker.test.tsx b/superset-frontend/src/components/Menu/LanguagePicker.test.tsx
new file mode 100644
index 0000000000000..ad494d620ca81
--- /dev/null
+++ b/superset-frontend/src/components/Menu/LanguagePicker.test.tsx
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { render, screen } from 'spec/helpers/testing-library';
+import LanguagePicker from './LanguagePicker';
+
+const mockedProps = {
+ locale: 'en',
+ languages: {
+ en: {
+ flag: 'us',
+ name: 'English',
+ url: '/lang/en',
+ },
+ it: {
+ flag: 'it',
+ name: 'Italian',
+ url: '/lang/it',
+ },
+ },
+};
+
+test('should render', () => {
+ const { container } = render();
+ expect(container).toBeInTheDocument();
+});
+
+test('should render the button', () => {
+ render();
+ const button = screen.getByRole('button');
+ expect(button).toHaveAttribute('href', '#');
+});
+
+test('should render the menuitem', () => {
+ render();
+ const menuitem = screen.getByRole('menuitem');
+ expect(menuitem).toHaveTextContent('Italian');
+});
diff --git a/superset-frontend/src/components/Menu/LanguagePicker.tsx b/superset-frontend/src/components/Menu/LanguagePicker.tsx
index f125c0aee62c4..63f6e6bae1bf0 100644
--- a/superset-frontend/src/components/Menu/LanguagePicker.tsx
+++ b/superset-frontend/src/components/Menu/LanguagePicker.tsx
@@ -51,6 +51,7 @@ export default function LanguagePicker({
}
+ data-test="language-picker"
>