test: UI tests for org chart mobile

fix(mobile): detach node before emptying hierarchy

fix(mobile): sibling group not rendering for first level
diff --git a/cypress/integration/test_organizational_chart_mobile.js b/cypress/integration/test_organizational_chart_mobile.js
new file mode 100644
index 0000000..6560512
--- /dev/null
+++ b/cypress/integration/test_organizational_chart_mobile.js
@@ -0,0 +1,182 @@
+context('Organizational Chart Mobile', () => {
+	before(() => {
+		cy.login();
+		cy.viewport(375, 667);
+		cy.visit('/app/website');
+
+		cy.visit(`app/organizational-chart`);
+		cy.wait(500);
+		cy.fill_field('company', 'Test Org Chart');
+		cy.get('body').click();
+		cy.wait(500);
+	});
+
+	beforeEach(() => {
+		cy.viewport(375, 667);
+		cy.wait(500);
+
+		cy.window().its('frappe').then(frappe => {
+			return frappe.call('erpnext.tests.ui_test_helpers.create_employee_records');
+		}).as('employee_records');
+	});
+
+	it('renders root nodes', () => {
+		// check rendered root nodes and the node name, title, connections
+		cy.get('.hierarchy-mobile').find('.root-level').children()
+			.should('have.length', 2)
+			.first()
+			.as('first-child');
+
+		cy.get('@first-child').get('.node-name').contains('Test Employee 1');
+		cy.get('@first-child').get('.node-info').find('.node-title').contains('CEO');
+		cy.get('@first-child').get('.node-info').find('.node-connections').contains('· 2');
+	});
+
+	it('expands root node', () => {
+		cy.get('@employee_records').then(employee_records => {
+			cy.get(`#${employee_records.message[1]}`)
+				.click()
+				.should('have.class', 'active');
+
+			// other root node removed
+			cy.get(`#${employee_records.message[0]}`).should('not.exist');
+
+			// children of active root node
+			cy.get('.hierarchy-mobile').find('.level').first().find('ul.node-children').children()
+				.should('have.length', 2)
+
+			cy.get(`[data-parent="${employee_records.message[1]}"]`).first().as('child-node');
+			cy.get('@child-node').should('be.visible');
+
+			cy.get('@child-node')
+				.get('.node-name')
+				.contains('Test Employee 4');
+
+			// connectors between root node and immediate children
+			cy.get(`path[data-parent="${employee_records.message[1]}"]`).as('connectors');
+			cy.get('@connectors')
+				.should('have.length', 2)
+				.should('be.visible')
+
+			cy.get('@connectors')
+				.first()
+				.invoke('attr', 'data-child')
+				.should('eq', employee_records.message[3]);
+		});
+	});
+
+	it('expands child node', () => {
+		cy.get('@employee_records').then(employee_records => {
+			cy.get(`#${employee_records.message[3]}`)
+				.click()
+				.should('have.class', 'active')
+				.as('expanded_node');
+
+			// 2 levels on screen; 1 on active path; 1 collapsed
+			cy.get('.hierarchy-mobile').children().should('have.length', 2);
+			cy.get(`#${employee_records.message[1]}`).should('have.class', 'active-path');
+
+			// children of expanded node visible
+			cy.get('@expanded_node')
+				.next()
+				.should('have.class', 'node-children')
+				.as('node-children');
+
+			cy.get('@node-children').children().should('have.length', 1);
+			cy.get('@node-children')
+				.first()
+				.get('.node-card')
+				.should('have.class', 'active-child')
+				.contains('Test Employee 7');
+
+			// orphan connectors removed
+			cy.get(`#connectors`).children().should('have.length', 2);
+		});
+	});
+
+	it('renders sibling group', () => {
+		cy.get('@employee_records').then(employee_records => {
+			// sibling group visible for parent
+			cy.get(`#${employee_records.message[1]}`)
+				.next()
+				.as('sibling_group');
+
+			cy.get('@sibling_group')
+				.should('have.attr', 'data-parent', 'undefined')
+				.should('have.class', 'node-group')
+				.and('have.class', 'collapsed')
+
+			cy.get('@sibling_group').get('.avatar-group').children().as('siblings');
+			cy.get('@siblings').should('have.length', 1);
+			cy.get('@siblings')
+				.first()
+				.should('have.attr', 'title', 'Test Employee 1');
+
+		});
+	});
+
+	it('expands previous level nodes', () => {
+		cy.get('@employee_records').then(employee_records => {
+			cy.get(`#${employee_records.message[6]}`)
+				.click()
+				.should('have.class', 'active');
+
+			// clicking on previous level node should remove all the nodes ahead
+			// and expand that node
+			cy.get(`#${employee_records.message[3]}`).click();
+			cy.get(`#${employee_records.message[3]}`)
+				.should('have.class', 'active')
+				.should('not.have.class', 'active-path');
+
+			cy.get(`#${employee_records.message[6]}`).should('have.class', 'active-child');
+			cy.get('.hierarchy-mobile').children().should('have.length', 2);
+			cy.get(`#connectors`).children().should('have.length', 2);
+		});
+	});
+
+	it('expands sibling group', () => {
+		cy.get('@employee_records').then(employee_records => {
+			// sibling group visible for parent
+			cy.get(`#${employee_records.message[6]}`).click()
+
+			cy.get(`#${employee_records.message[3]}`)
+				.next()
+				.click();
+
+			// siblings of parent should be visible
+			cy.get('.hierarchy-mobile').prev().as('sibling_group');
+			cy.get('@sibling_group')
+				.should('exist')
+				.should('have.class', 'sibling-group')
+				.should('not.have.class', 'collapsed');
+
+			cy.get(`#${employee_records.message[1]}`)
+				.should('be.visible')
+				.should('have.class', 'active');
+
+			cy.get(`[data-parent="${employee_records.message[1]}"]`)
+				.should('be.visible')
+				.should('have.length', 2)
+				.should('have.class', 'active-child');
+		});
+	});
+
+	it('goes to the respective level after clicking on non-collapsed sibling group', () => {
+		// click on non-collapsed sibling group
+		cy.get('.hierarchy-mobile')
+			.prev()
+			.click();
+
+		// should take you to that level
+		cy.get('.hierarchy-mobile').find('li.level .node-card').should('have.length', 2);
+	});
+
+	it('edit node navigates to employee master', () => {
+		cy.get('@employee_records').then(employee_records => {
+			cy.get(`#${employee_records.message[0]}`).find('.btn-edit-node')
+				.click();
+
+			cy.url().should('include', `/employee/${employee_records.message[0]}`);
+		});
+	});
+});
diff --git a/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js b/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
index 5a6f168..bd7946a 100644
--- a/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
+++ b/erpnext/public/js/hierarchy_chart/hierarchy_chart_mobile.js
@@ -128,6 +128,9 @@
 		if (this.$hierarchy)
 			this.$hierarchy.remove();
 
+		if (this.$sibling_group)
+			this.$sibling_group.empty();
+
 		this.$hierarchy = $(
 			`<ul class="hierarchy-mobile">
 				<li class="root-level level"></li>
@@ -173,7 +176,7 @@
 
 		if (this.$sibling_group) {
 			const sibling_parent = this.$sibling_group.find('.node-group').attr('data-parent');
-			if (node.parent_id !== sibling_parent)
+			if (node.parent_id !== undefined && node.parent_id != sibling_parent)
 				this.$sibling_group.empty();
 		}
 
@@ -376,9 +379,10 @@
 		let node_element = $(`#${node.id}`);
 
 		node_element.click(function() {
-			let el = $(this).detach();
+			let el = undefined;
 
 			if (node.is_root) {
+				el = $(this).detach();
 				me.$hierarchy.empty();
 				$(`#connectors`).empty();
 				me.add_node_to_hierarchy(el, node);
@@ -386,6 +390,7 @@
 				me.remove_levels_after_node(node);
 				me.remove_orphaned_connectors();
 			} else {
+				el = $(this).detach();
 				me.add_node_to_hierarchy(el, node);
 				me.collapse_node();
 			}
@@ -514,10 +519,10 @@
 		level = $('.hierarchy-mobile > li:eq('+ level + ')');
 		level.nextAll('li').remove();
 
-		let current_node = level.find(`#${node.id}`);
 		let node_object = this.nodes[node.id];
-
+		let current_node = level.find(`#${node.id}`).detach();
 		current_node.removeClass('active-child active-path');
+
 		node_object.expanded = 0;
 		node_object.$children = undefined;
 
diff --git a/erpnext/tests/ui_test_helpers.py b/erpnext/tests/ui_test_helpers.py
index 8e67b1c..99748dc 100644
--- a/erpnext/tests/ui_test_helpers.py
+++ b/erpnext/tests/ui_test_helpers.py
@@ -11,10 +11,11 @@
 	emp2 = create_employee('Test Employee 2', 'CTO')
 	emp3 = create_employee('Test Employee 3', 'Head of Marketing and Sales', emp1)
 	emp4 = create_employee('Test Employee 4', 'Project Manager', emp2)
-	emp5 = create_employee('Test Employee 5', 'Analyst', emp3)
-	emp6 = create_employee('Test Employee 6', 'Software Developer', emp4)
+	emp5 = create_employee('Test Employee 5', 'Engineer', emp2)
+	emp6 = create_employee('Test Employee 6', 'Analyst', emp3)
+	emp7 = create_employee('Test Employee 7', 'Software Developer', emp4)
 
-	employees = [emp1, emp2, emp3, emp4, emp5, emp6]
+	employees = [emp1, emp2, emp3, emp4, emp5, emp6, emp7]
 	return employees
 
 def create_company():